/* This file is part of TALER Copyright (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING.GPL. If not, see */ /** * @file taler_merchantdb_plugin.h * @brief database access for the merchant * @author Florian Dold * @author Christian Grothoff * @author Priscilla Huang */ #ifndef TALER_MERCHANTDB_PLUGIN_H #define TALER_MERCHANTDB_PLUGIN_H #include #include #include #include #include #include /** * Handle to interact with the database. */ struct TALER_MERCHANTDB_Plugin; GNUNET_NETWORK_STRUCT_BEGIN /** * @brief Hash over an order request, used for the idempotency check. */ struct TALER_MerchantPostDataHashP { /** * The authentication hash is a SHA-512 hash code. */ struct GNUNET_HashCode hash; }; /** * @brief Hash used for client authenticiation. Computed with a * `struct TALER_MerchantAuthenticationSaltP`. */ struct TALER_MerchantAuthenticationHashP { /** * The authentication hash is a SHA-512 hash code. * All zeros if authentication is off. */ struct GNUNET_HashCode hash; }; /** * @brief Salt used for client authenticiation. */ struct TALER_MerchantAuthenticationSaltP { /** * The authentication salt is a 256-bit value. */ uint32_t salt[256 / 8 / sizeof(uint32_t)]; /* = 8 */ }; /** * Format of the data hashed to generate the notification * string whenever the KYC status for an account has * changed. */ struct TALER_MERCHANTDB_MerchantKycStatusChangeEventP { /** * Type is TALER_DBEVENT_MERCHANT_EXCHANGE_KYC_STATUS_CHANGED. */ struct GNUNET_DB_EventHeaderP header; /** * Salted hash of the affected account. */ struct TALER_MerchantWireHashP h_wire; }; GNUNET_NETWORK_STRUCT_END /** * Current exposed deposit limits by an exchange * for a merchant (until other rules may apply). */ struct TALER_MERCHANTDB_DepositLimits { /** * Maximum amount to be deposited within @a timeframe. */ struct TALER_Amount threshold; /** * Timeframe over which the limit applies. */ struct GNUNET_TIME_Relative timeframe; /** * True if this is a soft limit that could be * raised (by AML staff or by passing KYC checks). */ bool soft_limit; }; /** * Details about a wire account of the merchant. */ struct TALER_MERCHANTDB_AccountDetails { /** * Hash of the wire details (@e payto_uri and @e salt). */ struct TALER_MerchantWireHashP h_wire; /** * Salt value used for hashing @e payto_uri. */ struct TALER_WireSaltP salt; /** * Instance ID. Do not free (may be aliased with * the instance ID given in the query!). * FIXME: set in all functions involving this struct! */ const char *instance_id; /** * Actual account address as a payto://-URI. */ struct TALER_FullPayto payto_uri; /** * Where can the taler-merchant-wirewatch helper * download information about incoming transfers? * NULL if not available. */ char *credit_facade_url; /** * JSON with credentials to use to access the * @e credit_facade_url. */ json_t *credit_facade_credentials; /** * Is the account set for active use in new contracts? */ bool active; }; /** * Binary login token. Just a vanilla token made out * of random bits. */ struct TALER_MERCHANTDB_LoginTokenP { /** * 32 bytes of entropy. */ uint64_t data[32 / 8]; }; /** * Authentication settings for an instance. */ struct TALER_MERCHANTDB_InstanceAuthSettings { /** * Hash used for authentication. All zero if authentication is off. */ struct TALER_MerchantAuthenticationHashP auth_hash; /** * Salt used to hash the "Authentication" header, the result must then * match the @e auth_hash. */ struct TALER_MerchantAuthenticationSaltP auth_salt; }; /** * General settings for an instance. */ struct TALER_MERCHANTDB_InstanceSettings { /** * prefix for the instance under "/instances/" */ char *id; /** * legal name of the instance */ char *name; /** * merchant's site url */ char *website; /** * email contact for customers */ char *email; /** * merchant's logo data uri */ char *logo; /** * Address of the business */ json_t *address; /** * jurisdiction of the business */ json_t *jurisdiction; /** * Use STEFAN curves to determine acceptable * fees by default (otherwise: accept no fees by default). */ bool use_stefan; /** * If the frontend does NOT specify an execution date, how long should * we tell the exchange to wait to aggregate transactions before * executing the wire transfer? This delay is added to the current * time when we generate the advisory execution time for the exchange. */ struct GNUNET_TIME_Relative default_wire_transfer_delay; /** * If the frontend does NOT specify a payment deadline, how long should * offers we make be valid by default? */ struct GNUNET_TIME_Relative default_pay_delay; }; /** * Typically called by `lookup_instances`. * * @param cls closure * @param merchant_pub public key of the instance * @param merchant_priv private key of the instance, NULL if not available * @param is general instance settings * @param ias instance authentication settings */ typedef void (*TALER_MERCHANTDB_InstanceCallback)( void *cls, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_InstanceSettings *is, const struct TALER_MERCHANTDB_InstanceAuthSettings *ias); /** * Callback invoked with information about a bank account. * * @param cls closure * @param merchant_priv private key of the merchant instance * @param ad details about the account */ typedef void (*TALER_MERCHANTDB_AccountCallback)( void *cls, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_AccountDetails *ad); /** * Determines the maximum @a amount for a particular * type of operation for a given @a exchange_url. * * @param cls closure * @param exchange_url base URL of the exchange to get * the limit for * @param[in,out] amount lowered to the maximum amount * allowed at the exchange */ typedef void (*TALER_MERCHANTDB_OperationLimitCallback)( void *cls, const char *exchange_url, struct TALER_Amount *amount); /** * Typically called by `lookup_products`. * * @param cls a `json_t *` JSON array to build * @param product_serial row ID of the product * @param product_id ID of the product */ typedef void (*TALER_MERCHANTDB_ProductsCallback)( void *cls, uint64_t product_serial, const char *product_id); /** * Details about a product. */ struct TALER_MERCHANTDB_ProductDetails { /** * Description of the product. */ char *description; /** * Internationalized description. */ json_t *description_i18n; /** * Unit in which the product is sold. */ char *unit; /** * Price per unit of the product. Zero to imply that the * product is not sold separately or that the price is not fixed. */ struct TALER_Amount price; /** * Base64-encoded product image, or an empty string. */ char *image; /** * List of taxes the merchant pays for this product. Never NULL, * but can be an empty array. */ json_t *taxes; /** * Number of units of the product in stock in sum in total, including all * existing sales and lost product, in product-specific units. UINT64_MAX * indicates "infinite". */ uint64_t total_stock; /** * Number of units of the product in sold, in product-specific units. */ uint64_t total_sold; /** * Number of units of stock lost. */ uint64_t total_lost; /** * Identifies where the product is in stock, possibly an empty map. */ json_t *address; /** * Identifies when the product will be restocked. 0 for unknown, * #GNUNET_TIME_UNIT_FOREVER_ABS for never. */ struct GNUNET_TIME_Timestamp next_restock; /** * Minimum required age for consumers buying this product. * Default is 0. Only enforced of an exchange supports age * restrictions. */ uint32_t minimum_age; }; /** * Typically called by `lookup_all_products`. * * @param cls a `json_t *` JSON array to build * @param product_serial row ID of the product * @param product_id ID of the product * @param pd full product details * @param num_categories length of @a categories array * @param categories array of categories the * product is in */ typedef void (*TALER_MERCHANTDB_ProductCallback)( void *cls, uint64_t product_serial, const char *product_id, const struct TALER_MERCHANTDB_ProductDetails *pd, size_t num_categories, const uint64_t *categories); /** * Typically called by `lookup_templates`. * * @param cls closure * @param template_id ID of the template * @param template_description description of the template */ typedef void (*TALER_MERCHANTDB_TemplatesCallback)( void *cls, const char *template_id, const char *template_description); /** * Typically called by `lookup_otp_devices`. * * @param cls closure * @param otp_id ID of the OTP device * @param otp_description description of the OTP device */ typedef void (*TALER_MERCHANTDB_OtpDeviceCallback)( void *cls, const char *otp_id, const char *otp_description); /** * Details about a template. */ struct TALER_MERCHANTDB_TemplateDetails { /** * Description of the template. */ char *template_description; /** * In this template contract, we can have additional information. */ json_t *template_contract; /** * ID of the OTP device linked to the template, or NULL. */ char *otp_id; /** * Editable default values for fields not specified * in the @e template_contract. NULL if the user * cannot edit anything. */ json_t *editable_defaults; }; /** * Details about an OTP device. */ struct TALER_MERCHANTDB_OtpDeviceDetails { /** * Description of the device. */ char *otp_description; /** * Current usage counter value. */ uint64_t otp_ctr; /** * Base64-encoded key. */ char *otp_key; /** * Algorithm used to compute purchase confirmations. */ enum TALER_MerchantConfirmationAlgorithm otp_algorithm; }; /** * Typically called by `lookup_categories`. * * @param cls closure * @param category_id ID of the category * @param category_name name of the category * @param category_name_i18n translations of the @a category_name * @param product_count number of products in the category */ typedef void (*TALER_MERCHANTDB_CategoriesCallback)( void *cls, uint64_t category_id, const char *category_name, const json_t *category_name_i18n, uint64_t product_count); /** * Details about a product category. */ struct TALER_MERCHANTDB_ProductSummary { /** * ID of the product. */ char *product_id; /** * Description for the product. */ char *description; /** * Translation of the @e description. */ json_t *description_i18n; }; /** * Details about a product category. */ struct TALER_MERCHANTDB_CategoryDetails { /** * Name of the category. */ char *category_name; /** * Translations of the name of the category. */ json_t *category_name_i18n; /** * Products in the category. */ struct TALER_MERCHANTDB_ProductSummary *products; /** * Length of the @e products array. */ unsigned int num_products; }; /** * Typically called by `lookup_webhooks`. * * @param cls a `json_t *` JSON array to build * @param webhook_id ID of the webhook * @param event_type event of the webhook */ typedef void (*TALER_MERCHANTDB_WebhooksCallback)( void *cls, const char *webhook_id, const char *event_type); /** * Details about a webhook. */ struct TALER_MERCHANTDB_WebhookDetails { /** * event of the webhook. */ char *event_type; /** * URL of the webhook. The customer will be redirected on this url. */ char *url; /** * Http method used by the webhook. */ char *http_method; /** * Header template of the webhook. */ char *header_template; /** * Body template of the webhook. */ char *body_template; }; /** * Typically called by `lookup_webhook_by_event`. * * @param cls a `json_t *` JSON array to build * @param webhook_serial reference to the configured webhook template. * @param event_type which type of event triggers this type of webhook * @param url the HTTP URL to make the webhook request to * @param http_method HTTP method use for the webhook * @param header_template template for the header of the webhook * @param body_template template for the body of the webhook */ typedef void (*TALER_MERCHANTDB_WebhookDetailCallback)( void *cls, uint64_t webhook_serial, const char *event_type, const char *url, const char *http_method, const char *header_template, const char *body_template); /** * Typically called by `lookup_pending_webhooks`. * * @param cls a `json_t *` JSON array to build * @param webhook_pending_serial reference to the configured webhook template. * @param next_attempt is the time we should make the next request to the webhook. * @param retries how often have we tried this request to the webhook. * @param url to make request to * @param http_method use for the webhook * @param header of the webhook * @param body of the webhook */ typedef void (*TALER_MERCHANTDB_PendingWebhooksCallback)( void *cls, uint64_t webhook_pending_serial, struct GNUNET_TIME_Absolute next_attempt, uint32_t retries, const char *url, const char *http_method, const char *header, const char *body); /** * Details about the pending webhook. */ struct TALER_MERCHANTDB_PendingWebhookDetails { /** * Identifies when we should make the next request to the webhook. 0 for unknown, * #GNUNET_TIME_UNIT_FOREVER_ABS for never. */ struct GNUNET_TIME_Absolute next_attempt; /** * How often have we tried this request so far. */ uint32_t retries; /** * URL of the webhook. The customer will be redirected on this url. */ char *url; /** * Http method used for the webhook. */ char *http_method; /** * Header of the webhook. */ char *header; /** * Body of the webhook. */ char *body; }; /** * Filter preferences. */ struct TALER_MERCHANTDB_OrderFilter { /** * Filter orders by this fulfillment URL. */ const char *fulfillment_url; /** * Filter orders by this session ID. */ const char *session_id; /** * Filter by payment status. */ enum TALER_EXCHANGE_YesNoAll paid; /** * Filter by refund status. */ enum TALER_EXCHANGE_YesNoAll refunded; /** * Filter by wire transfer status. */ enum TALER_EXCHANGE_YesNoAll wired; /** * Filter orders by date, exact meaning depends on @e delta. */ struct GNUNET_TIME_Timestamp date; /** * Filter orders by order serial number, exact meaning depends on @e delta. */ uint64_t start_row; /** * takes value of the form N (-N), so that at most N values strictly older * (younger) than start and date are returned. */ int64_t delta; /** * Timeout for long-polling. */ struct GNUNET_TIME_Relative timeout; }; /** * Typically called by `lookup_orders`. * * @param cls a `json_t *` JSON array to build * @param order_id ID of the order * @param order_serial row of the order in the database * @param timestamp creation time of the order in the database */ typedef void (*TALER_MERCHANTDB_OrdersCallback)(void *cls, const char *order_id, uint64_t order_serial, struct GNUNET_TIME_Timestamp timestamp); /** * Function called with information about a coin that was deposited. * * @param cls closure * @param exchange_url exchange where @a coin_pub was deposited * @param coin_pub public key of the coin * @param amount_with_fee amount the exchange will deposit for this coin * @param deposit_fee fee the exchange will charge for this coin * @param refund_fee fee the exchange will charge for refunding this coin */ typedef void (*TALER_MERCHANTDB_DepositsCallback)( void *cls, const char *exchange_url, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_Amount *refund_fee); /** * Function called with information about a refund. * * @param cls closure * @param coin_pub public coin from which the refund comes from * @param refund_amount refund amount which is being taken from @a coin_pub */ typedef void (*TALER_MERCHANTDB_RefundCallback)( void *cls, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *refund_amount); /** * Typically called by `lookup_transfer_details_by_order`. * * @param cls closure * @param wtid wire transfer subject of the wire transfer for the coin * @param exchange_url base URL of the exchange that made the payment * @param execution_time when was the payment made * @param deposit_value contribution of the coin to the total wire transfer value * @param deposit_fee deposit fee charged by the exchange for the coin * @param transfer_confirmed did the merchant confirm that a wire transfer with * @a wtid over the total amount happened? */ typedef void (*TALER_MERCHANTDB_OrderTransferDetailsCallback)( void *cls, const struct TALER_WireTransferIdentifierRawP *wtid, const char *exchange_url, struct GNUNET_TIME_Timestamp execution_time, const struct TALER_Amount *deposit_value, const struct TALER_Amount *deposit_fee, bool transfer_confirmed); /** * Function called with detailed information about a refund. * * @param cls closure * @param refund_serial unique serial number of the refund * @param timestamp time of the refund (for grouping of refunds in the wallet UI) * @param coin_pub public coin from which the refund comes from * @param exchange_url URL of the exchange that issued @a coin_pub * @param rtransaction_id identificator of the refund * @param reason human-readable explanation of the refund * @param refund_amount refund amount which is being taken from @a coin_pub * @param pending true if the this refund was not yet processed by the wallet/exchange */ typedef void (*TALER_MERCHANTDB_RefundDetailCallback)( void *cls, uint64_t refund_serial, struct GNUNET_TIME_Timestamp timestamp, const struct TALER_CoinSpendPublicKeyP *coin_pub, const char *exchange_url, uint64_t rtransaction_id, const char *reason, const struct TALER_Amount *refund_amount, bool pending); /** * Function called from ``account_kyc_get_status`` * with KYC status information for this merchant. * * @param cls closure * @param h_wire hash of the wire account * @param payto_uri payto:// URI of the merchant's bank account * @param exchange_url base URL of the exchange for which this is a status * @param last_check when did we last get an update on our KYC status from the exchange * @param kyc_ok true if we satisfied the KYC requirements * @param access_token access token for the KYC SPA, NULL if we cannot access it yet (need KYC auth wire transfer) * @param last_http_status last HTTP status from /kyc-check * @param last_ec last Taler error code from /kyc-check * @param in_aml_review true if the account is pending review * @param jlimits JSON array of applicable AccountLimits, or NULL if unknown (like defaults apply) */ typedef void (*TALER_MERCHANTDB_KycCallback)( void *cls, const struct TALER_MerchantWireHashP *h_wire, struct TALER_FullPayto payto_uri, const char *exchange_url, struct GNUNET_TIME_Timestamp last_check, bool kyc_ok, const struct TALER_AccountAccessTokenP *access_token, unsigned int last_http_status, enum TALER_ErrorCode last_ec, bool in_aml_review, const json_t *jlimits); /** * Results from trying to increase a refund. */ enum TALER_MERCHANTDB_RefundStatus { /** * Refund amount exceeds legal exchange limits. */ TALER_MERCHANTDB_RS_LEGAL_FAILURE = -5, /** * Refund amount currency does not match original payment. */ TALER_MERCHANTDB_RS_BAD_CURRENCY = -4, /** * Refund amount exceeds original payment. */ TALER_MERCHANTDB_RS_TOO_HIGH = -3, /** * Hard database failure. */ TALER_MERCHANTDB_RS_HARD_ERROR = -2, /** * Soft database failure. */ TALER_MERCHANTDB_RS_SOFT_ERROR = -1, /** * Order not found. */ TALER_MERCHANTDB_RS_NO_SUCH_ORDER = 0, /** * Refund is now at or above the requested amount. */ TALER_MERCHANTDB_RS_SUCCESS = 1 }; /** * Function called with information about a wire transfer identifier. * * @param cls closure * @param order_id the order to which the deposits belong * @param deposit_value the amount deposited under @a order_id * @param deposit_fee the fee charged for @a deposit_value */ typedef void (*TALER_MERCHANTDB_TransferSummaryCallback)( void *cls, const char *order_id, const struct TALER_Amount *deposit_value, const struct TALER_Amount *deposit_fee); /** * Function called with information about wire transfers * that taler-merchant-exchange still needs to process. * * @param cls closure * @param rowid row of the transfer in the merchant database * @param instance_id instance that received the transfer * @param exchange_url base URL of the exchange that initiated the transfer * @param payto_uri account of the merchant that received the transfer * @param wtid wire transfer subject identifying the aggregation * @param total total amount that was wired * @param next_attempt when should we next try to interact with the exchange */ typedef void (*TALER_MERCHANTDB_OpenTransferCallback)( void *cls, uint64_t rowid, const char *instance_id, const char *exchange_url, struct TALER_FullPayto payto_uri, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *total, struct GNUNET_TIME_Absolute next_attempt); /** * Callback for results from `lookup_pending_deposits`. * * @param cls NULL * @param deposit_serial identifies the deposit operation * @param wire_deadline when is the wire due * @param retry_backoff current value of the retry backoff * @param h_contract_terms hash of the contract terms * @param merchant_priv private key of the merchant * @param instance_id name of the instance * @param h_wire hash of the merchant's wire account into * @param amount_with_fee amount the exchange will deposit for this coin * @param deposit_fee fee the exchange will charge for this coin which the deposit was made * @param coin_pub public key of the deposited coin */ typedef void (*TALER_MERCHANTDB_PendingDepositsCallback) ( void *cls, uint64_t deposit_serial, struct GNUNET_TIME_Absolute wire_deadline, struct GNUNET_TIME_Relative retry_backoff, const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_MerchantPrivateKeyP *merchant_priv, const char *instance_id, const struct TALER_MerchantWireHashP *h_wire, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub); /** * Function called with detailed information about a wire transfer and * the underlying deposits that are being aggregated. * * @param cls closure * @param current_offset offset in the exchange reply we are at * @param ttd details about the transfer at @a current_offset */ typedef void (*TALER_MERCHANTDB_TransferDetailsCallback)( void *cls, unsigned int current_offset, const struct TALER_TrackTransferDetails *ttd); /** * Function called with information about a accounts * the wirewatcher should monitor. * * @param cls closure * @param instance instance that owns the account * @param payto_uri account URI * @param credit_facade_url URL for the credit facade * @param credit_facade_credentials account access credentials * @param last_serial last transaction serial (inclusive) we have seen from this account */ typedef void (*TALER_MERCHANTDB_WirewatchWorkCallback)( void *cls, const char *instance, struct TALER_FullPayto payto_uri, const char *credit_facade_url, const json_t *credit_facade_credentials, uint64_t last_serial); /** * Function called with information about a wire transfer. * * @param cls closure with a `json_t *` array to build up the response * @param credit_amount how much was wired to the merchant (minus fees) * @param wtid wire transfer identifier * @param payto_uri target account that received the wire transfer * @param exchange_url base URL of the exchange that made the wire transfer * @param transfer_serial_id serial number identifying the transfer in the backend * @param execution_time when did the exchange make the transfer, #GNUNET_TIME_UNIT_FOREVER_ABS * if it did not yet happen * @param verified true if we checked the exchange's answer and liked it, * false there is a problem (verification failed or did not yet happen) * @param confirmed true if the merchant confirmed this wire transfer * false if it is so far only claimed to have been made by the exchange */ typedef void (*TALER_MERCHANTDB_TransferCallback)( void *cls, const struct TALER_Amount *credit_amount, const struct TALER_WireTransferIdentifierRawP *wtid, struct TALER_FullPayto payto_uri, const char *exchange_url, uint64_t transfer_serial_id, struct GNUNET_TIME_Timestamp execution_time, bool verified, bool confirmed); /** * If the given account is feasible, add it to the array * of accounts we return. * * @param cls closure * @param payto_uri URI of the account * @param conversion_url URL of a conversion service * @param debit_restrictions restrictions for debits from account * @param credit_restrictions restrictions for credits to account * @param master_sig signature affirming the account */ typedef void (*TALER_MERCHANTDB_ExchangeAccountCallback) ( void *cls, struct TALER_FullPayto payto_uri, const char *conversion_url, const json_t *debit_restrictions, const json_t *credit_restrictions, const struct TALER_MasterSignatureP *master_sig); /** * Function called with information about a coin that was deposited. * * @param cls closure * @param deposit_serial which deposit operation is this about * @param exchange_url URL of the exchange that issued the coin * @param h_wire hash of merchant's wire details * @param deposit_timestamp when was the deposit made * @param amount_with_fee amount the exchange will deposit for this coin * @param deposit_fee fee the exchange will charge for this coin * @param coin_pub public key of the coin */ typedef void (*TALER_MERCHANTDB_DepositedCoinsCallback)( void *cls, uint64_t deposit_serial, const char *exchange_url, const struct TALER_MerchantWireHashP *h_wire, struct GNUNET_TIME_Timestamp deposit_timestamp, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_CoinSpendPublicKeyP *coin_pub); /** * Function called with information about a coin that was deposited. * * @param cls closure * @param exchange_url URL of the exchange that issued the coin * @param amount_with_fee amount the exchange will deposit for this coin * @param deposit_fee fee the exchange will charge for this coin * @param refund_fee fee the exchange will charge for refunding this coin * @param wire_fee wire fee the exchange charges * @param h_wire hash of merchant's wire details * @param deposit_timestamp when did the exchange receive the deposit * @param refund_deadline until when are refunds allowed * @param exchange_sig signature by the exchange * @param exchange_pub exchange signing key used for @a exchange_sig */ typedef void (*TALER_MERCHANTDB_CoinDepositCallback)( void *cls, const char *exchange_url, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_Amount *refund_fee, const struct TALER_Amount *wire_fee, const struct TALER_MerchantWireHashP *h_wire, struct GNUNET_TIME_Timestamp deposit_timestamp, struct GNUNET_TIME_Timestamp refund_deadline, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub); /** * Possible token family kinds. */ enum TALER_MERCHANTDB_TokenFamilyKind { /** * Token family representing a discount token */ TALER_MERCHANTDB_TFK_Discount = 0, /** * Token family representing a subscription token */ TALER_MERCHANTDB_TFK_Subscription = 1, }; /** * Typically called by `lookup_token_families`. * * @param cls a `json_t *` JSON array to build * @param slug slug of the token family * @param name name of the token family * @param start_time start time of the token family's validity period * @param expiration end time of the token family's validity period * @param kind kind of the token family */ typedef void (*TALER_MERCHANTDB_TokenFamiliesCallback)( void *cls, const char *slug, const char *name, struct GNUNET_TIME_Timestamp start_time, struct GNUNET_TIME_Timestamp expiration, const char *kind); /** * Details about a token family. */ struct TALER_MERCHANTDB_TokenFamilyDetails { /** * Token family slug used for identification. */ char *slug; /** * User readable name of the token family. */ char *name; /** * Description of the token family. */ char *description; /** * Internationalized token family description. */ json_t *description_i18n; /** * Start time of the token family duration. */ struct GNUNET_TIME_Timestamp valid_after; /** * End time of the token family duration. */ struct GNUNET_TIME_Timestamp valid_before; /** * Validity duration of the token family. */ struct GNUNET_TIME_Relative duration; /** * Rounding duration of the token family. */ struct GNUNET_TIME_Relative rounding; /** * Token family kind. */ enum TALER_MERCHANTDB_TokenFamilyKind kind; /** * Counter for each issued token of this family. */ uint64_t issued; /** * Counter for each used token of this family. */ uint64_t used; }; /** * Details about a token key. */ struct TALER_MERCHANTDB_TokenFamilyKeyDetails { /** * Tokens signed with this key are valid from this date on. */ struct GNUNET_TIME_Timestamp valid_after; /** * Tokens signed with this key are valid until this date. */ struct GNUNET_TIME_Timestamp valid_before; /** * Token family public key. */ struct TALER_TokenIssuePublicKeyP pub; /** * Token family private key. */ struct TALER_TokenIssuePrivateKeyP priv; /** * Details about the token family this key belongs to. */ struct TALER_MERCHANTDB_TokenFamilyDetails token_family; }; /** * Details about a spent token. */ struct TALER_MERCHANTDB_SpentTokenDetails { /** * Public key of the spent token. */ struct TALER_TokenUsePublicKeyP pub; /** * Signature that this token was spent on the specified order. */ struct TALER_TokenUseSignatureP sig; /** * Blind signature for the spent token to prove validity of it. */ struct TALER_TokenIssueBlindSignatureP blind_sig; }; /** * Function called with information about a token that was used. * * @param cls closure * @param spent_token_serial which used token is this about * @param h_contract_terms hash of the contract terms this token was used on * @param h_issue_pub hash of the token issue public key * @param use_pub token use public key * @param use_sig token use signature * @param issue_sig unblinded token issue signature */ typedef void (*TALER_MERCHANTDB_UsedTokensCallback)( void *cls, uint64_t spent_token_serial, const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_TokenIssuePublicKeyHashP *h_issue_pub, const struct TALER_TokenUsePublicKeyP *use_pub, const struct TALER_TokenUseSignatureP *use_sig, const struct TALER_TokenIssueSignatureP *issue_sig); /** * Handle to interact with the database. * * Functions ending with "_TR" run their OWN transaction scope * and MUST NOT be called from within a transaction setup by the * caller. Functions ending with "_NT" require the caller to * setup a transaction scope. Functions without a suffix are * simple, single SQL queries that MAY be used either way. */ struct TALER_MERCHANTDB_Plugin { /** * Closure for all callbacks. */ void *cls; /** * Name of the library which generated this plugin. Set by the * plugin loader. */ char *library_name; /** * Connect to the database. * * @param cls closure */ enum GNUNET_GenericReturnValue (*connect)(void *cls); /** * Drop merchant tables. Used for testcases and to reset the DB. * * @param cls closure * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ enum GNUNET_GenericReturnValue (*drop_tables)(void *cls); /** * Initialize merchant tables * * @param cls closure * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure */ enum GNUNET_GenericReturnValue (*create_tables)(void *cls); /** * Register callback to be invoked on events of type @a es. * * @param cls database context to use * @param es specification of the event to listen for * @param timeout how long to wait for the event * @param cb function to call when the event happens, possibly * multiple times (until cancel is invoked) * @param cb_cls closure for @a cb * @return handle useful to cancel the listener */ struct GNUNET_DB_EventHandler * (*event_listen)(void *cls, const struct GNUNET_DB_EventHeaderP *es, struct GNUNET_TIME_Relative timeout, GNUNET_DB_EventCallback cb, void *cb_cls); /** * Stop notifications. * * @param eh handle to unregister. */ void (*event_listen_cancel)(struct GNUNET_DB_EventHandler *eh); /** * Notify all that listen on @a es of an event. * * @param cls database context to use * @param es specification of the event to generate * @param extra additional event data provided * @param extra_size number of bytes in @a extra */ void (*event_notify)(void *cls, const struct GNUNET_DB_EventHeaderP *es, const void *extra, size_t extra_size); /** * Do a pre-flight check that we are not in an uncommitted transaction. If * we are, die. Does not return anything, as we will continue regardless of * the outcome. * * @param cls the `struct PostgresClosure` with the plugin-specific state */ void (*preflight) (void *cls); /** * Start a transaction. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param name unique name identifying the transaction (for debugging), * must point to a constant * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue (*start)(void *cls, const char *name); /** * Start a transaction with isolation level 'read committed'. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @param name unique name identifying the transaction (for debugging), * must point to a constant * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue (*start_read_committed)(void *cls, const char *name); /** * Roll back the current transaction of a database connection. * * @param cls the `struct PostgresClosure` with the plugin-specific state */ void (*rollback) (void *cls); /** * Commit the current transaction of a database connection. * * @param cls the `struct PostgresClosure` with the plugin-specific state * @return transaction status */ enum GNUNET_DB_QueryStatus (*commit)(void *cls); /** * Lookup all of the instances this backend has configured. * * @param cls closure * @param active_only only find 'active' instances * @param cb function to call on all instances found * @param cb_cls closure for @a cb */ enum GNUNET_DB_QueryStatus (*lookup_instances)(void *cls, bool active_only, TALER_MERCHANTDB_InstanceCallback cb, void *cb_cls); /** * Lookup one of the instances this backend has configured. * * @param cls closure * @param id ID of instance to look up * @param active_only only find 'active' instances * @param cb function to call on all instances found * @param cb_cls closure for @a cb */ enum GNUNET_DB_QueryStatus (*lookup_instance)(void *cls, const char *id, bool active_only, TALER_MERCHANTDB_InstanceCallback cb, void *cb_cls); /** * Lookup authentication data of an instance. * * @param cls closure * @param instance_id instance to query * @param[out] ias where to store the auth data */ enum GNUNET_DB_QueryStatus (*lookup_instance_auth)(void *cls, const char *instance_id, struct TALER_MERCHANTDB_InstanceAuthSettings *ias); /** * Insert information about an instance into our database. * * @param cls closure * @param merchant_pub public key of the instance * @param merchant_priv private key of the instance * @param is details about the instance * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_instance)(void *cls, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_InstanceSettings *is, const struct TALER_MERCHANTDB_InstanceAuthSettings *ias); /** * Insert information about an instance's account into our database. * * @param cls closure * @param account_details details about the account * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_account)( void *cls, const struct TALER_MERCHANTDB_AccountDetails *account_details); /** * Insert instance login token into our database. * * @param cls closure * @param id identifier of the instance * @param token value of the token * @param creation_time the current time * @param expiration_time when does the token expire * @param validity_scope scope of the token * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_login_token)( void *cls, const char *id, const struct TALER_MERCHANTDB_LoginTokenP *token, struct GNUNET_TIME_Timestamp creation_time, struct GNUNET_TIME_Timestamp expiration_time, uint32_t validity_scope); /** * Lookup information about a login token from database. * * @param cls closure * @param id identifier of the instance * @param token value of the token * @param[out] expiration_time set to expiration time * @param[out] validity_scope set to scope of the token * @return database result code */ enum GNUNET_DB_QueryStatus (*select_login_token)( void *cls, const char *id, const struct TALER_MERCHANTDB_LoginTokenP *token, struct GNUNET_TIME_Timestamp *expiration_time, uint32_t *validity_scope); /** * Delete login token from database. * * @param cls closure * @param id identifier of the instance * @param token value of the token * @return database result code */ enum GNUNET_DB_QueryStatus (*delete_login_token)( void *cls, const char *id, const struct TALER_MERCHANTDB_LoginTokenP *token); /** * Update information about an instance's account into our database. * * @param cls closure * @param id identifier of the instance * @param h_wire which account to update * @param credit_facade_url new facade URL, can be NULL * @param credit_facade_credentials new credentials, can be NULL * @return database result code */ enum GNUNET_DB_QueryStatus (*update_account)( void *cls, const char *id, const struct TALER_MerchantWireHashP *h_wire, const char *credit_facade_url, const json_t *credit_facade_credentials); /** * Obtain information about an instance's accounts. * * @param cls closure * @param id identifier of the instance * @param cb function to call on each account * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*select_accounts)( void *cls, const char *id, TALER_MERCHANTDB_AccountCallback cb, void *cb_cls); /** * Obtain detailed information about an instance's account. * * @param cls closure * @param id identifier of the instance * @param h_wire wire hash of the account * @param[out] ad account details returned * @return database result code */ enum GNUNET_DB_QueryStatus (*select_account)( void *cls, const char *id, const struct TALER_MerchantWireHashP *h_wire, struct TALER_MERCHANTDB_AccountDetails *ad); /** * Obtain detailed information about an instance's account. * * @param cls closure * @param id identifier of the instance * @param payto_uri URI of the account * @param[out] ad account details returned * @return database result code */ enum GNUNET_DB_QueryStatus (*select_account_by_uri)( void *cls, const char *id, struct TALER_FullPayto payto_uri, struct TALER_MERCHANTDB_AccountDetails *ad); /** * Delete private key of an instance from our database. * * @param cls closure * @param merchant_id identifier of the instance * @return database result code */ enum GNUNET_DB_QueryStatus (*delete_instance_private_key)( void *cls, const char *merchant_id); /** * Purge an instance and all associated information from our database. * Highly likely to cause undesired data loss. Use with caution. * * @param cls closure * @param merchant_id identifier of the instance * @return database result code */ enum GNUNET_DB_QueryStatus (*purge_instance)(void *cls, const char *merchant_id); /** * Update information about an instance into our database. * * @param cls closure * @param is details about the instance * @return database result code */ enum GNUNET_DB_QueryStatus (*update_instance)(void *cls, const struct TALER_MERCHANTDB_InstanceSettings *is); /** * Update information about an instance's authentication settings * into our database. * * @param cls closure * @param merchant_id merchant backend instance ID * @param ias instance auth settings * @return database result code */ enum GNUNET_DB_QueryStatus (*update_instance_auth)( void *cls, const char *merchant_id, const struct TALER_MERCHANTDB_InstanceAuthSettings *ias); /** * Set an instance's account in our database to "inactive". * * @param cls closure * @param merchant_id merchant backend instance ID * @param h_wire hash of the wire account to set to inactive * @return database result code */ enum GNUNET_DB_QueryStatus (*inactivate_account)(void *cls, const char *merchant_id, const struct TALER_MerchantWireHashP *h_wire); /** * Set an instance's account in our database to "active". * * @param cls closure * @param merchant_id merchant backend instance ID * @param h_wire hash of the wire account to set to active * @return database result code */ enum GNUNET_DB_QueryStatus (*activate_account)(void *cls, const char *merchant_id, const struct TALER_MerchantWireHashP *h_wire); /** * Check an instance's account's KYC status. * * @param cls closure * @param merchant_id merchant backend instance ID * @param h_wire hash of the wire account to check, * NULL to check all accounts of the merchant * @param exchange_url base URL of the exchange to check, * NULL to check all exchanges * @param kyc_cb KYC status callback to invoke * @param kyc_cb_cls closure for @a kyc_cb * @return database result code */ enum GNUNET_DB_QueryStatus (*account_kyc_get_status)( void *cls, const char *merchant_id, const struct TALER_MerchantWireHashP *h_wire, const char *exchange_url, TALER_MERCHANTDB_KycCallback kyc_cb, void *kyc_cb_cls); /** * Check an account's KYC status at an exchange. * * @param cls closure * @param merchant_payto_uri merchant backend instance ID * @param instance_id the instance for which to check * @param exchange_url base URL of the exchange * @param[out] auth_ok true if @a access_token was set * @param[out] access_token set to access token for /kyc-info * @param[out] kyc_ok true if no urgent KYC work must be done for this account * @param[out] last_http_status set to last HTTP status from exchange on /kyc-check * @param[out] last_ec set to last Taler error code from exchange on /kyc-check * @param[out] last_kyc_check set to time of last KYC check * @param[out] aml_review set to true if the account is under AML review (if this exposed) * @param[out] jlimits set to JSON array with AccountLimits, NULL if unknown (and likely defaults apply or KYC auth is urgently needed, see @a auth_ok) * @return database result code */ enum GNUNET_DB_QueryStatus (*get_kyc_status)( void *cls, struct TALER_FullPayto merchant_account_uri, const char *instance_id, const char *exchange_url, bool *auth_ok, struct TALER_AccountAccessTokenP *access_token, bool *kyc_ok, unsigned int *last_http_status, enum TALER_ErrorCode *last_ec, struct GNUNET_TIME_Timestamp *last_kyc_check, bool *aml_review, json_t **jlimits); /** * Check an account's KYC limits at an exchange. * * @param cls closure * @param merchant_payto_uri merchant backend instance ID * @param instance_id the instance for which to check * @param exchange_url base URL of the exchange * @param[out] kyc_ok true if no urgent KYC work must be done for this account * @param[out] jlimits set to JSON array with AccountLimits, NULL if unknown (and likely defaults apply or KYC auth is urgently needed, see @a auth_ok) * @return database result code */ enum GNUNET_DB_QueryStatus (*get_kyc_limits)( void *cls, struct TALER_FullPayto merchant_account_uri, const char *instance_id, const char *exchange_url, bool *kyc_ok, json_t **jlimits); /** * Update an instance's account's KYC status. * * @param cls closure * @param merchant_id merchant backend instance ID * @param h_wire hash of the wire account to check * @param exchange_url base URL of the exchange to check * @param timestamp timestamp to store * @param exchange_http_status HTTP status code returned last by the exchange * @param exchange_ec_code Taler error code returned last by the exchange * @param access_token access token for the KYC process, NULL for none * @param jlimits JSON array with AccountLimits returned by the exchange * @param in_aml_review true if the exchange says the account is under review * @param kyc_ok current KYC status (true for satisfied) * @return database result code */ enum GNUNET_DB_QueryStatus (*account_kyc_set_status)( void *cls, const char *merchant_id, const struct TALER_MerchantWireHashP *h_wire, const char *exchange_url, struct GNUNET_TIME_Timestamp timestamp, unsigned int exchange_http_status, enum TALER_ErrorCode exchange_ec_code, const struct TALER_AccountAccessTokenP *access_token, const json_t *jlimits, bool in_aml_review, bool kyc_ok); /** * Set an instance's account's KYC status to failed. * * @param cls closure * @param merchant_id merchant backend instance ID * @param h_wire hash of the wire account to check * @param exchange_url base URL of the exchange to check * @param timestamp timestamp to store * @param exchange_http_status HTTP status code returned last by the exchange * @param kyc_ok current KYC status (should be false) * @return database result code */ enum GNUNET_DB_QueryStatus (*account_kyc_set_failed) ( void *cls, const char *merchant_id, const struct TALER_MerchantWireHashP *h_wire, const char *exchange_url, struct GNUNET_TIME_Timestamp timestamp, unsigned int exchange_http_status, bool kyc_ok); /** * Lookup all of the products the given instance has configured. * * @param cls closure * @param instance_id instance to lookup products for * @param offset transfer_serial number of the transfer we want to offset from * @param limit number of entries to return, negative for descending, * positive for ascending * @param cb function to call on all products found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_products)(void *cls, const char *instance_id, uint64_t offset, int64_t limit, TALER_MERCHANTDB_ProductsCallback cb, void *cb_cls); /** * Lookup full details of all of the products the given instance has configured (expensive). * * @param cls closure * @param instance_id instance to lookup products for * @param cb function to call on all products found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_all_products)(void *cls, const char *instance_id, TALER_MERCHANTDB_ProductCallback cb, void *cb_cls); /** * Lookup details about a particular product. * * @param cls closure * @param instance_id instance to lookup products for * @param product_id product to lookup * @param[out] pd set to the product details on success, can be NULL * (in that case we only want to check if the product exists) * @param[out] num_categories set to length of @a categories array * @param[out] categories set to array of categories the * product is in, caller must free() it. * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_product)(void *cls, const char *instance_id, const char *product_id, struct TALER_MERCHANTDB_ProductDetails *pd, size_t *num_categories, uint64_t **categories); /** * Delete information about a product. Note that the transaction must * enforce that no stocks are currently locked. * * @param cls closure * @param instance_id instance to delete product of * @param product_id product to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if locks prevent deletion OR product unknown */ enum GNUNET_DB_QueryStatus (*delete_product)(void *cls, const char *instance_id, const char *product_id); /** * Insert details about a particular product. * * @param cls closure * @param instance_id instance to insert product for * @param product_id product identifier of product to insert * @param pd the product details to insert * @param num_cats length of @a cats array * @param cats array of categories the product is in * @param[out] no_instance set to true if @a instance_id is unknown * @param[out] conflict set to true if a conflicting * product already exists in the database * @param[out] no_cat set to index of non-existing category from @a cats, or -1 if all @a cats were found * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_product)(void *cls, const char *instance_id, const char *product_id, const struct TALER_MERCHANTDB_ProductDetails *pd, size_t num_cats, const uint64_t *cats, bool *no_instance, bool *conflict, ssize_t *no_cat); /** * Update details about a particular product. Note that the * transaction must enforce that the sold/stocked/lost counters * are not reduced (i.e. by expanding the WHERE clause on the existing * values). * * @param cls closure * @param instance_id instance to lookup products for * @param product_id product to lookup * @param pd product details with updated values * @param num_cats length of @a cats array * @param cats number of categories the product is in * @param[out] no_instance the update failed as the instance is unknown * @param[out] no_cat set to -1 on success, otherwise the update failed and this is set * to the index of a category in @a cats that is unknown * @param[out] no_product the @a product_id is unknown * @param[out] lost_reduced the update failed as the counter of units lost would have been lowered * @param[out] sold_reduced the update failed as the counter of units sold would have been lowered * @param[out] stocked_reduced the update failed as the counter of units stocked would have been lowered * @return database result code */ enum GNUNET_DB_QueryStatus (*update_product)(void *cls, const char *instance_id, const char *product_id, const struct TALER_MERCHANTDB_ProductDetails *pd, size_t num_cats, const uint64_t *cats, bool *no_instance, ssize_t *no_cat, bool *no_product, bool *lost_reduced, bool *sold_reduced, bool *stocked_reduced); /** * Lock stocks of a particular product. Note that the transaction must * enforce that the "stocked-sold-lost >= locked" constraint holds. * * @param cls closure * @param instance_id instance to lookup products for * @param product_id product to lookup * @param uuid the UUID that holds the lock * @param quantity how many units should be locked * @param expiration_time when should the lock expire * @return database result code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the * product is unknown OR if there insufficient stocks remaining */ enum GNUNET_DB_QueryStatus (*lock_product)(void *cls, const char *instance_id, const char *product_id, const struct GNUNET_Uuid *uuid, uint64_t quantity, struct GNUNET_TIME_Timestamp expiration_time); /** * Release all expired product locks, including * those from expired offers -- across all * instances. * * @param cls closure * @return database result code */ enum GNUNET_DB_QueryStatus (*expire_locks)(void *cls); /** * Delete information about an order. Note that the transaction must * enforce that the order is not awaiting payment anymore. * * @param cls closure * @param instance_id instance to delete order of * @param order_id order to delete * @param force force deletion of claimed but unpaid orders * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if locks prevent deletion OR order unknown */ enum GNUNET_DB_QueryStatus (*delete_order)(void *cls, const char *instance_id, const char *order_id, bool force); /** * Retrieve order given its @a order_id and the @a instance_id. * * @param cls closure * @param instance_id instance to obtain order of * @param order_id order id used to perform the lookup * @param[out] claim_token the claim token generated for the order, * NULL to only test if the order exists * @param[out] h_post_data set to the hash of the POST data that created the order * @param[out] contract_terms where to store the retrieved contract terms, * NULL to only test if the order exists * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_order)(void *cls, const char *instance_id, const char *order_id, struct TALER_ClaimTokenP *claim_token, struct TALER_MerchantPostDataHashP *h_post_data, json_t **contract_terms); /** * Retrieve order summary given its @a order_id and the @a instance_id. * * @param cls closure * @param instance_id instance to obtain order of * @param order_id order id used to perform the lookup * @param[out] timestamp when was the order created * @param[out] order_serial under which serial do we keep this order * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_order_summary)(void *cls, const char *instance_id, const char *order_id, struct GNUNET_TIME_Timestamp *timestamp, uint64_t *order_serial); /** * Retrieve orders given the @a instance_id. * * @param cls closure * @param instance_id instance to obtain order of * @param of filter to apply when looking up orders * @param[out] contract_terms where to store the retrieved contract terms, * NULL to only test if the order exists * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_orders)(void *cls, const char *instance_id, const struct TALER_MERCHANTDB_OrderFilter *of, TALER_MERCHANTDB_OrdersCallback cb, void *cb_cls); /** * Insert order into db. * * @param cls closure * @param instance_id identifies the instance responsible for the order * @param order_id alphanumeric string that uniquely identifies the order * @param session_id session ID for the order * @param h_post_data hash of the POST data for idempotency checks * @param pay_deadline how long does the customer have to pay for the order * @param claim_token token to use for access control * @param contract_terms proposal data to store * @param pos_key encoded key for payment verification * @param pos_algorithm algorithm to compute the payment verification * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_order)(void *cls, const char *instance_id, const char *order_id, const char *session_id, const struct TALER_MerchantPostDataHashP *h_post_data, struct GNUNET_TIME_Timestamp pay_deadline, const struct TALER_ClaimTokenP *claim_token, const json_t *contract_terms, const char *pos_key, enum TALER_MerchantConfirmationAlgorithm pos_algorithm); /** * Release an inventory lock by UUID. Releases ALL stocks locked under * the given UUID. * * @param cls closure * @param uuid the UUID to release locks for * @return transaction status, * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS means there are no locks under @a uuid * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT indicates success */ enum GNUNET_DB_QueryStatus (*unlock_inventory)(void *cls, const struct GNUNET_Uuid *uuid); /** * Lock inventory stock to a particular order. * * @param cls closure * @param instance_id identifies the instance responsible for the order * @param order_id alphanumeric string that uniquely identifies the order * @param product_id uniquely identifies the product to be locked * @param quantity how many units should be locked to the @a order_id * @return transaction status, * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS means there are insufficient stocks * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT indicates success */ enum GNUNET_DB_QueryStatus (*insert_order_lock)(void *cls, const char *instance_id, const char *order_id, const char *product_id, uint64_t quantity); /** * Retrieve contract terms given its @a order_id * * @param cls closure * @param instance_id instance's identifier * @param order_id order_id used to lookup. * @param[out] contract_terms where to store the result, NULL to only check for existence * @param[out] order_serial set to the order's serial number * @param[out] paid set to true if the order is fully paid * @param[out] claim_token set to the claim token, NULL to only check for existence * @param[out] pos_key encoded key for payment verification * @param[out] pos_algorithm set to algorithm to compute the payment verification * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_contract_terms2)( void *cls, const char *instance_id, const char *order_id, json_t **contract_terms, uint64_t *order_serial, bool *paid, struct TALER_ClaimTokenP *claim_token, char **pos_key, enum TALER_MerchantConfirmationAlgorithm *pricing_algorithm); /** * Retrieve contract terms given its @a order_id * * @param cls closure * @param instance_id instance's identifier * @param order_id order_id used to lookup * @param session_id session_id to compare, can be NULL * @param[out] contract_terms where to store the result, NULL to only check for existence * @param[out] order_serial set to the order's serial number * @param[out] paid set to true if the order is fully paid * @param[out] wired set to true if the exchange wired the funds * @param[out] session_matches set to true if @a session_id matches session stored for this contract * @param[out] claim_token set to the claim token, NULL to only check for existence * @param[out] choice_index set to the choice index, -1 if not set * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_contract_terms3)( void *cls, const char *instance_id, const char *order_id, const char *session_id, json_t **contract_terms, uint64_t *order_serial, bool *paid, bool *wired, bool *session_matches, struct TALER_ClaimTokenP *claim_token, int16_t *choice_index); /** * Retrieve contract terms given its @a order_id * * @param cls closure * @param instance_id instance's identifier * @param order_id order_id used to lookup. * @param[out] contract_terms where to store the result, NULL to only check for existence * @param[out] order_serial set to the order's serial number * @param[out] claim_token set to the claim token, NULL to only check for existence * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_contract_terms)( void *cls, const char *instance_id, const char *order_id, json_t **contract_terms, uint64_t *order_serial, struct TALER_ClaimTokenP *claim_token); /** * Store contract terms given its @a order_id. Note that some attributes are * expected to be calculated inside of the function, like the hash of the * contract terms (to be hashed), the creation_time and pay_deadline (to be * obtained from the merchant_orders table). The "session_id" should be * initially set to the empty string. The "fulfillment_url" and "refund_deadline" * must be extracted from @a contract_terms. * * @param cls closure * @param instance_id instance's identifier * @param order_id order_id used to store * @param claim_token the token belonging to the order * @param[out] order_serial set to the serial of the order * @return transaction status, #GNUNET_DB_STATUS_HARD_ERROR if @a contract_terms * is malformed */ enum GNUNET_DB_QueryStatus (*insert_contract_terms)( void *cls, const char *instance_id, const char *order_id, json_t *contract_terms, uint64_t *order_serial); /** * Update the contract terms stored for @a order_id. Note that some attributes are * expected to be calculated inside of the function, like the hash of the * contract terms (to be hashed), the creation_time and pay_deadline (to be * obtained from the merchant_orders table). The "session_id" should be * initially set to the empty string. The "fulfillment_url" and "refund_deadline" * must be extracted from @a contract_terms. * * @param cls closure * @param instance_id instance's identifier * @param order_id order_id used to store * @param contract_terms contract to store * @return transaction status, #GNUNET_DB_STATUS_HARD_ERROR if @a contract_terms * is malformed */ enum GNUNET_DB_QueryStatus (*update_contract_terms)(void *cls, const char *instance_id, const char *order_id, json_t *contract_terms); /** * Delete information about a contract. Note that the transaction must * enforce that the contract is not awaiting payment anymore AND was not * paid, or is past the legal expiration. * * @param cls closure * @param instance_id instance to delete order of * @param order_id order to delete * @param legal_expiration how long do we need to keep (paid) contracts on * file for legal reasons (i.e. taxation) * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if locks prevent deletion OR order unknown */ enum GNUNET_DB_QueryStatus (*delete_contract_terms)(void *cls, const char *instance_id, const char *order_id, struct GNUNET_TIME_Relative legal_expiration); /** * Lookup information about coins that were successfully deposited for a * given contract. * * @param cls closure * @param instance_id instance to lookup deposits for * @param h_contract_terms proposal data's hashcode * @param cb function to call with payment data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_deposits)(void *cls, const char *instance_id, const struct TALER_PrivateContractHashP *h_contract_terms, TALER_MERCHANTDB_DepositsCallback cb, void *cb_cls); /** * Insert an exchange signing key into our database. * * @param cls closure * @param master_pub exchange master public key used for @a master_sig * @param exchange_pub exchange signing key to insert * @param start_date when does the signing key become valid * @param expire_date when does the signing key stop being used * @param end_date when does the signing key become void as proof * @param master_sig signature of @a master_pub over the @a exchange_pub and the dates */ enum GNUNET_DB_QueryStatus (*insert_exchange_signkey)( void *cls, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_ExchangePublicKeyP *exchange_pub, struct GNUNET_TIME_Timestamp start_date, struct GNUNET_TIME_Timestamp expire_date, struct GNUNET_TIME_Timestamp end_date, const struct TALER_MasterSignatureP *master_sig); /** * Insert deposit confirmation from the exchange into the database. * * @param cls closure * @param instance_id instance to lookup deposits for * @param deposit_timestamp time when the exchange generated the deposit confirmation * @param h_contract_terms proposal data's hashcode * @param exchange_url URL of the exchange that issued @a coin_pub * @param wire_transfer_deadline when do we expect the wire transfer from the exchange * @param total_without_fees deposited total in the batch without fees * @param wire_fee wire fee the exchange charges * @param h_wire hash of the wire details of the target account of the merchant * @param exchange_sig signature from exchange that coin was accepted * @param exchange_pub signing key that was used for @a exchange_sig * @param[out] batch_deposit_serial_id set to the table row * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_deposit_confirmation)( void *cls, const char *instance_id, struct GNUNET_TIME_Timestamp deposit_timestamp, const struct TALER_PrivateContractHashP *h_contract_terms, const char *exchange_url, struct GNUNET_TIME_Timestamp wire_transfer_deadline, const struct TALER_Amount *total_without_fees, const struct TALER_Amount *wire_fee, const struct TALER_MerchantWireHashP *h_wire, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub, uint64_t *batch_deposit_serial_id); /** * Insert information about coin deposited as part of * a batch into the database. * * @param cls closure * @param offset offset of the coin in the batch * @param deposit_confirmation_serial_id deposit confirmation for the batch the coin is part of * @param coin_pub public key of the coin * @param coin_sig deposit signature of the coin * @param amount_with_fee amount the exchange will deposit for this coin * @param deposit_fee fee the exchange will charge for this coin * @param refund_fee fee the exchange will charge for refunds of coin * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_deposit)( void *cls, uint32_t offset, uint64_t deposit_confirmation_serial_id, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_Amount *amount_with_fee, const struct TALER_Amount *deposit_fee, const struct TALER_Amount *refund_fee); /** * Obtain refunds associated with a contract. * * @param cls closure, typically a connection to the db * @param instance_id instance to lookup refunds for * @param h_contract_terms hash code of the contract * @param rc function to call for each coin on which there is a refund * @param rc_cls closure for @a rc * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_refunds)(void *cls, const char *instance_id, const struct TALER_PrivateContractHashP *h_contract_terms, TALER_MERCHANTDB_RefundCallback rc, void *rc_cls); /** * Retrieve details about tokens that were used for an order. * * @param cls closure * @param order_serial identifies the order * @param cb function to call for each used token * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_spent_tokens_by_order)(void *cls, uint64_t order_serial, TALER_MERCHANTDB_UsedTokensCallback cb, void *cb_cls); /** * Mark contract as paid and store the current @a session_id * for which the contract was paid. Deletes the underlying order * and marks the locked stocks of the order as sold. * * @param cls closure * @param instance_id instance to mark contract as paid for * @param h_contract_terms hash of the contract that is now paid * @param session_id the session that paid the contract * @return transaction status */ enum GNUNET_DB_QueryStatus (*mark_contract_paid)( void *cls, const char *instance_id, const struct TALER_PrivateContractHashP *h_contract_terms, const char *session_id); /** * Function called during aborts to refund a coin. Marks the * respective coin as refunded. * * @param cls closure * @param instance_id instance to refund payment for * @param h_contract_terms hash of the contract to refund coin for * @param refund_timestamp timestamp of when the coin was refunded * @param coin_pub public key of the coin to refund (fully) * @param reason text justifying the refund * @return transaction status * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a coin_pub is unknown to us; * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid, * regardless of whether it actually increased the refund */ enum GNUNET_DB_QueryStatus (*refund_coin)(void *cls, const char *instance_id, const struct TALER_PrivateContractHashP *h_contract_terms, struct GNUNET_TIME_Timestamp refund_timestamp, const struct TALER_CoinSpendPublicKeyP *coin_pub, const char *reason); /** * Retrieve contract terms given its @a order_id * * @param cls closure * @param instance_id instance's identifier * @param order_id order to lookup contract for * @param[out] h_contract_terms set to the hash of the contract. * @param[out] paid set to the payment status of the contract * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_order_status)(void *cls, const char *instance_id, const char *order_id, struct TALER_PrivateContractHashP *h_contract_terms, bool *paid); /** * Retrieve contract terms given its @a order_serial * * @param cls closure * @param instance_id instance's identifier * @param order_serial serial ID of the order to look up * @param[out] order_id set to ID of the order * @param[out] h_contract_terms set to the hash of the contract. * @param[out] paid set to the payment status of the contract * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_order_status_by_serial)(void *cls, const char *instance_id, uint64_t order_serial, char **order_id, struct TALER_PrivateContractHashP * h_contract_terms, bool *paid); /** * Retrieve details about coins that were deposited for an order. * * @param cls closure * @param order_serial identifies the order * @param cb function to call for each deposited coin * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_deposits_by_order)(void *cls, uint64_t order_serial, TALER_MERCHANTDB_DepositedCoinsCallback cb, void *cb_cls); /** * Retrieve wire transfer details for all deposits associated with * a given @a order_serial. * * @param cls closure * @param order_serial identifies the order * @param cb function called with the wire transfer details * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_transfer_details_by_order)( void *cls, uint64_t order_serial, TALER_MERCHANTDB_OrderTransferDetailsCallback cb, void *cb_cls); /** * Update transfer status. * * @param cls closure * @param exchange_url the exchange that made the transfer * @param wtid wire transfer subject * @param next_attempt when should we try again (if ever) * @param ec current error state of checking the transfer * @param failed true if validation has failed for good * @param verified true if validation has succeeded for good * @return database transaction status */ enum GNUNET_DB_QueryStatus (*update_transfer_status)( void *cls, const char *exchange_url, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute next_attempt, enum TALER_ErrorCode ec, bool failed, bool verified); /** * Retrieve wire transfer details of wire details * that taler-merchant-exchange still needs to * investigate. * * @param cls closure * @param limit maximum number of results to return * @param cb function called with the wire transfer data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*select_open_transfers)( void *cls, uint64_t limit, TALER_MERCHANTDB_OpenTransferCallback cb, void *cb_cls); /** * Insert wire transfer details for a deposit. * * @param cls closure * @param deposit_serial serial number of the deposit * @param dd deposit transfer data from the exchange to store * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_deposit_to_transfer)(void *cls, uint64_t deposit_serial, const struct TALER_EXCHANGE_DepositData *dd); /** * Set 'wired' status for an order to 'true'. * * @param cls closure * @param order_serial serial number of the order * @return transaction status */ enum GNUNET_DB_QueryStatus (*mark_order_wired)(void *cls, uint64_t order_serial); /** * Function called when some backoffice staff decides to award or * increase the refund on an existing contract. This function * MUST be called from within a transaction scope setup by the * caller as it executes multiple SQL statements. * * @param cls closure * @param instance_id instance identifier * @param order_id the order to increase the refund for * @param refund maximum refund to return to the customer for this contract * @param olc function to call to obtain legal refund * limits per exchange, NULL for no limits * @param olc_cls closure for @a olc * @param reason 0-terminated UTF-8 string giving the reason why the customer * got a refund (free form, business-specific) * @return transaction status * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a refund is ABOVE the amount we * were originally paid and thus the transaction failed; * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the request is valid, * regardless of whether it actually increased the refund beyond * what was already refunded (idempotency!) */ enum TALER_MERCHANTDB_RefundStatus (*increase_refund)( void *cls, const char *instance_id, const char *order_id, const struct TALER_Amount *refund, TALER_MERCHANTDB_OperationLimitCallback olc, void *olc_cls, const char *reason); /** * Obtain detailed refund data associated with a contract. * * @param cls closure, typically a connection to the db * @param instance_id instance to lookup refunds for * @param h_contract_terms hash code of the contract * @param rc function to call for each coin on which there is a refund * @param rc_cls closure for @a rc * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_refunds_detailed)( void *cls, const char *instance_id, const struct TALER_PrivateContractHashP *h_contract_terms, TALER_MERCHANTDB_RefundDetailCallback rc, void *rc_cls); /** * Insert refund proof data from the exchange into the database. * * @param cls closure * @param refund_serial serial number of the refund * @param exchange_sig signature from exchange that coin was refunded * @param exchange_pub signing key that was used for @a exchange_sig * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_refund_proof)( void *cls, uint64_t refund_serial, const struct TALER_ExchangeSignatureP *exchange_sig, const struct TALER_ExchangePublicKeyP *exchange_pub); /** * Insert used token into the database. * * @param cls closure * @param h_contract_terms hash of the contract the token was used for * @param h_issue_pub hash of the token issue public key * @param use_pub token use public key * @param use_sig token use signature * @param issue_sig token issue signature * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_spent_token)( void *cls, const struct TALER_PrivateContractHashP * h_contract_terms, const struct TALER_TokenIssuePublicKeyHashP *h_issue_pub, const struct TALER_TokenUsePublicKeyP *use_pub, const struct TALER_TokenUseSignatureP *use_sig, const struct TALER_TokenIssueSignatureP *issue_sig); /** * Insert issued token into the database. * * @param cls closure * @param h_contract_terms hash of the contract the token was issued for * @param h_issue_pub hash of the token issue public key used to sign the issued token * @param blind_sig resulting blind token issue signature * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_issued_token)( void *cls, const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_TokenIssuePublicKeyHashP *h_issue_pub, const struct TALER_TokenIssueBlindSignatureP *blind_sig); /** * Lookup refund proof data. * * @param cls closure * @param refund_serial serial number of the refund * @param[out] exchange_sig set to signature from exchange * @param[out] exchange_pub signing key that was used for @a exchange_sig * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_refund_proof)( void *cls, uint64_t refund_serial, struct TALER_ExchangeSignatureP *exchange_sig, struct TALER_ExchangePublicKeyP *exchange_pub); /** * Retrieve the order ID that was used to pay for a resource within a session. * * @param cls closure * @param instance_id instance to lookup the order from * @param fulfillment_url URL that canonically identifies the resource * being paid for * @param session_id session id * @param allow_refunded_for_repurchase true to include refunded orders in repurchase detection * @param[out] order_id location to store the order ID that was used when * paying for the resource URL * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_order_by_fulfillment)( void *cls, const char *instance_id, const char *fulfillment_url, const char *session_id, bool allow_refunded_for_repurchase, char **order_id); /** * Update information about progress made by taler-merchant-wirewatch. * * @param cls closure * @param instance which instance does the account belong to * @param payto_uri which account is this about * @param last_serial last serial imported from the bank * @return transaction status */ enum GNUNET_DB_QueryStatus (*update_wirewatch_progress)( void *cls, const char *instance, struct TALER_FullPayto payto_uri, uint64_t last_serial); /** * Select information about accounts which taler-merchant-wirewatch should work on. * * @param cls closure * @param cb function to call with results * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*select_wirewatch_accounts)( void *cls, TALER_MERCHANTDB_WirewatchWorkCallback cb, void *cb_cls); /** * Insert information about a wire transfer the merchant has received. * * @param cls closure * @param instance_id instance to lookup the order from * @param exchange_url which exchange made the transfer * @param wtid identifier of the wire transfer * @param credit_amount how much did we receive * @param payto_uri what is the merchant's bank account that received the transfer * @param confirmed whether the transfer was confirmed by the merchant or * was merely claimed by the exchange at this point * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_transfer)( void *cls, const char *instance_id, const char *exchange_url, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *credit_amount, struct TALER_FullPayto payto_uri, bool confirmed); /** * Delete information about a transfer. Note that transfers * confirmed by the exchange cannot be deleted anymore. * * @param cls closure * @param instance_id instance to delete transfer of * @param transfer_serial_id transfer to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if deletion is prohibited OR transfer is unknown */ enum GNUNET_DB_QueryStatus (*delete_transfer)(void *cls, const char *instance_id, uint64_t transfer_serial_id); /** * Check if information about a transfer exists with the * backend. Returns no data, only the query status. * * @param cls closure * @param instance_id instance to delete transfer of * @param transfer_serial_id transfer to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT * if the transfer record exists */ enum GNUNET_DB_QueryStatus (*check_transfer_exists)(void *cls, const char *instance_id, uint64_t transfer_serial_id); /** * Lookup account serial by payto URI. * * @param cls closure * @param instance_id instance to lookup the account from * @param payto_uri what is the merchant's bank account to lookup * @param[out] account_serial serial number of the account * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_account)(void *cls, const char *instance_id, struct TALER_FullPayto payto_uri, uint64_t *account_serial); /** * Insert information about a wire transfer the merchant has received. * * @param cls closure * @param instance_id instance to provide transfer details for * @param exchange_url which exchange made the transfer * @param payto_uri what is the merchant's bank account that received the transfer * @param wtid identifier of the wire transfer * @param td transfer details to store * @return transaction status, * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the @a wtid and @a exchange_uri are not known for this @a instance_id * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT on success */ enum GNUNET_DB_QueryStatus (*insert_transfer_details)( void *cls, const char *instance_id, const char *exchange_url, struct TALER_FullPayto payto_uri, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_EXCHANGE_TransferData *td); /** * Obtain information about wire fees charged by an exchange, * including signature (so we have proof). * * @param cls closure * @param master_pub master public key of the exchange * @param h_wire_method hash of wire method * @param contract_date date of the contract to use for the lookup * @param[out] fees set to wire fees charged * @param[out] start_date start of fee being used * @param[out] end_date end of fee being used * @param[out] master_sig signature of exchange over fee structure * @return transaction status code */ enum GNUNET_DB_QueryStatus (*lookup_wire_fee)( void *cls, const struct TALER_MasterPublicKeyP *master_pub, const char *wire_method, struct GNUNET_TIME_Timestamp contract_date, struct TALER_WireFeeSet *fees, struct GNUNET_TIME_Timestamp *start_date, struct GNUNET_TIME_Timestamp *end_date, struct TALER_MasterSignatureP *master_sig); /** * Lookup information about coin payments by @a h_contract_terms and * @a coin_pub. * * @param cls closure * @param instance_id instance to lookup payments for * @param h_contract_terms proposal data's hashcode * @param coin_pub public key to use for the search * @param cb function to call with payment data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_deposits_by_contract_and_coin)( void *cls, const char *instance_id, const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, TALER_MERCHANTDB_CoinDepositCallback cb, void *cb_cls); /** * Lookup transfer status. * * @param cls closure * @param instance_id the instance to look up details at * @param exchange_url the exchange that made the transfer * @param wtid wire transfer subject * @param[out] total_amount amount that was debited from our * aggregate balance at the exchange (in total, sum of * the wire transfer amount and the @a wire_fee) * @param[out] wire_fee the wire fee the exchange charged (only set if @a have_exchange_sig is true) * @param[out] exchange_amount the amount the exchange claims was transferred (only set if @a have_exchange_sig is true) * @param[out] execution_time when the transfer was executed by the exchange (only set if @a have_exchange_sig is true) * @param[out] have_exchange_sig do we have a response from the exchange about this transfer * @param[out] verified did we confirm the transfer was OK * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_transfer)( void *cls, const char *instance_id, const char *exchange_url, const struct TALER_WireTransferIdentifierRawP *wtid, struct TALER_Amount *total_amount, struct TALER_Amount *wire_fee, struct TALER_Amount *exchange_amount, struct GNUNET_TIME_Timestamp *execution_time, bool *have_exchange_sig, bool *verified); /** * Set transfer status to confirmed. * * @param cls closure * @param instance_id instance to lookup payments for * @param exchange_url the exchange that made the transfer * @param wtid wire transfer subject * @param amount confirmed amount of the wire transfer * @return transaction status */ enum GNUNET_DB_QueryStatus (*set_transfer_status_to_confirmed)( void *cls, const char *instance_id, const char *exchange_url, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *amount); /** * Lookup transfer summary (used if we already verified the details). * * @param cls closure * @param exchange_url the exchange that made the transfer * @param wtid wire transfer subject * @param cb function to call with detailed transfer data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_transfer_summary)( void *cls, const char *exchange_url, const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MERCHANTDB_TransferSummaryCallback cb, void *cb_cls); /** * Lookup transfer details. Used if we still need to verify the details. * * @param cls closure * @param exchange_url the exchange that made the transfer * @param wtid wire transfer subject * @param cb function to call with detailed transfer data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_transfer_details)( void *cls, const char *exchange_url, const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MERCHANTDB_TransferDetailsCallback cb, void *cb_cls); /** * Lookup transfers. * * @param cls closure * @param instance_id instance to lookup payments for * @param payto_uri account that we are interested in transfers to * @param before timestamp for the earliest transfer we care about * @param after timestamp for the last transfer we care about * @param limit number of entries to return, negative for descending in execution time, * positive for ascending in execution time * @param offset transfer_serial number of the transfer we want to offset from * @param verified filter transfers by verification status * @param cb function to call with detailed transfer data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_transfers)( void *cls, const char *instance_id, struct TALER_FullPayto payto_uri, struct GNUNET_TIME_Timestamp before, struct GNUNET_TIME_Timestamp after, int64_t limit, uint64_t offset, enum TALER_EXCHANGE_YesNoAll yna, TALER_MERCHANTDB_TransferCallback cb, void *cb_cls); /** * Store information about wire fees charged by an exchange, * including signature (so we have proof). * * @param cls closure * @param master_pub master public key of the exchange * @param h_wire_method hash of wire method * @param fees wire fees charged * @param start_date start of fee being used * @param end_date end of fee being used * @param master_sig signature of exchange over fee structure * @return transaction status code */ enum GNUNET_DB_QueryStatus (*store_wire_fee_by_exchange)( void *cls, const struct TALER_MasterPublicKeyP *master_pub, const struct GNUNET_HashCode *h_wire_method, const struct TALER_WireFeeSet *fees, struct GNUNET_TIME_Timestamp start_date, struct GNUNET_TIME_Timestamp end_date, const struct TALER_MasterSignatureP *master_sig); /** * Delete information about wire accounts of an exchange. (Used when we got new account data.) * * @param cls closure * @param master_pub public key of the exchange * @return transaction status code */ enum GNUNET_DB_QueryStatus (*delete_exchange_accounts)( void *cls, const struct TALER_MasterPublicKeyP *master_pub); /** * Return information about wire accounts of an exchange. * * @param cls closure * @param master_pub public key of the exchange * @param cb function to call on each account * @param cb_cls closure for @a cb * @return transaction status code */ enum GNUNET_DB_QueryStatus (*select_accounts_by_exchange)( void *cls, const struct TALER_MasterPublicKeyP *master_pub, TALER_MERCHANTDB_ExchangeAccountCallback cb, void *cb_cls); /** * Insert information about a wire account of an exchange. * * @param cls closure * @param master_pub public key of the exchange * @param payto_uri URI of the bank account * @param conversion_url conversion service, NULL if there is no conversion required * @param debit_restrictions JSON array of debit restrictions on the account * @param credit_restrictions JSON array of debit restrictions on the account * @param master_sig signature affirming the account of the exchange * @return transaction status code */ enum GNUNET_DB_QueryStatus (*insert_exchange_account)( void *cls, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_FullPayto payto_uri, const char *conversion_url, const json_t *debit_restrictions, const json_t *credit_restrictions, const struct TALER_MasterSignatureP *master_sig); /** * Lookup all of the templates the given instance has configured. * * @param cls closure * @param instance_id instance to lookup template for * @param cb function to call on all template found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_templates)(void *cls, const char *instance_id, TALER_MERCHANTDB_TemplatesCallback cb, void *cb_cls); /** * Lookup details about a particular template. * * @param cls closure * @param instance_id instance to lookup template for * @param template_id template to lookup * @param[out] td set to the template details on success, can be NULL * (in that case we only want to check if the template exists) * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_template)(void *cls, const char *instance_id, const char *template_id, struct TALER_MERCHANTDB_TemplateDetails *td); /** * Delete information about a template. * * @param cls closure * @param instance_id instance to delete template of * @param template_id template to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if template unknown. */ enum GNUNET_DB_QueryStatus (*delete_template)(void *cls, const char *instance_id, const char *template_id); /** * Insert details about a particular template. * * @param cls closure * @param instance_id instance to insert template for * @param template_id template identifier of template to insert * @param otp_serial_id 0 if no OTP device is associated * @param td the template details to insert * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_template)(void *cls, const char *instance_id, const char *template_id, uint64_t otp_serial_id, const struct TALER_MERCHANTDB_TemplateDetails *td); /** * Update details about a particular template. * * @param cls closure * @param instance_id instance to update template for * @param template_id template to update * @param td update to the template details on success, can be NULL * (in that case we only want to check if the template exists) * @return database result code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the template * does not yet exist. */ enum GNUNET_DB_QueryStatus (*update_template)(void *cls, const char *instance_id, const char *template_id, const struct TALER_MERCHANTDB_TemplateDetails *td); /** * Delete information about an OTP device. * * @param cls closure * @param instance_id instance to delete OTP device of * @param otp_id otp device to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if template unknown. */ enum GNUNET_DB_QueryStatus (*delete_otp)(void *cls, const char *instance_id, const char *otp_id); /** * Insert details about a particular OTP device. * * @param cls closure * @param instance_id instance to insert OTP device for * @param otp_id otp identifier of OTP device to insert * @param td the OTP device details to insert * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_otp)(void *cls, const char *instance_id, const char *otp_id, const struct TALER_MERCHANTDB_OtpDeviceDetails *td); /** * Update details about a particular OTP device. * * @param cls closure * @param instance_id instance to update OTP device for * @param otp_id OTP device to update * @param td update to the OTP device details on success, can be NULL * (in that case we only want to check if the template exists) * @return database result code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the template * does not yet exist. */ enum GNUNET_DB_QueryStatus (*update_otp)(void *cls, const char *instance_id, const char *otp_id, const struct TALER_MERCHANTDB_OtpDeviceDetails *td); /** * Lookup all of the OTP devices the given instance has configured. * * @param cls closure * @param instance_id instance to lookup OTP devices for * @param cb function to call on all OTP devices found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_otp_devices)(void *cls, const char *instance_id, TALER_MERCHANTDB_OtpDeviceCallback cb, void *cb_cls); /** * Lookup details about an OTP device. * * @param cls closure * @param instance_id instance to lookup template for * @param otp_id OTP device to lookup * @param[out] td set to the OTP device details on success, can be NULL * (in that case we only want to check if the template exists) * @return database result code */ enum GNUNET_DB_QueryStatus (*select_otp)(void *cls, const char *instance_id, const char *otp_id, struct TALER_MERCHANTDB_OtpDeviceDetails *td); /** * Lookup serial number of an OTP device. * * @param cls closure * @param instance_id instance to lookup template for * @param otp_id OTP device to lookup * @param[out] serial set to the OTP device serial number * @return database result code */ enum GNUNET_DB_QueryStatus (*select_otp_serial)(void *cls, const char *instance_id, const char *otp_id, uint64_t *serial); /** * Delete information about a product category. * * @param cls closure * @param instance_id instance to delete category of * @param category_id identifies the category to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if template unknown. */ enum GNUNET_DB_QueryStatus (*delete_category)(void *cls, const char *instance_id, uint64_t category_id); /** * Insert new product category. * * @param cls closure * @param instance_id instance to insert OTP device for * @param category_name name of the category * @param category_name_i18n translations of the category name * @param[out] category_id set to the category id on success * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_category)(void *cls, const char *instance_id, const char *category_name, const json_t *category_name_i18n, uint64_t *category_id); /** * Update descriptions of a product category. * * @param cls closure * @param instance_id instance to update OTP device for * @param category_id category to update * @param category_name name of the category * @param category_name_i18n translations of the category name * @return database result code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the template * does not yet exist. */ enum GNUNET_DB_QueryStatus (*update_category)(void *cls, const char *instance_id, uint64_t category_id, const char *category_name, const json_t *category_name_i18n); /** * Lookup all of the product categories the given instance has configured. * * @param cls closure * @param instance_id instance to lookup OTP devices for * @param cb function to call on all categories found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_categories)(void *cls, const char *instance_id, TALER_MERCHANTDB_CategoriesCallback cb, void *cb_cls); /** * Lookup details about product category. * * @param cls closure * @param instance_id instance to lookup template for * @param category_id category to update * @param[out] cd set to the category details on success, can be NULL * (in that case we only want to check if the category exists) * @param[out] num_products set to length of @a products array * @param[out] products set to buffer with @a num_products 0-terminated strings with the product IDs, caller must free() it. * @return database result code */ enum GNUNET_DB_QueryStatus (*select_category)(void *cls, const char *instance_id, uint64_t category_id, struct TALER_MERCHANTDB_CategoryDetails *cd, size_t *num_products, char **products); /** * Lookup details about product category by name. * * @param cls closure * @param instance_id instance to lookup template for * @param category_name category name to look for * @param[out] name_i18n category name translation * @param[out] category_id category ID * @return database result code */ enum GNUNET_DB_QueryStatus (*select_category_by_name)(void *cls, const char *instance_id, const char *category_name, json_t **name_i18n, uint64_t *category_id); /** * Lookup all of the webhooks the given instance has configured. * * @param cls closure * @param instance_id instance to lookup webhook for * @param cb function to call on all webhook found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_webhooks)(void *cls, const char *instance_id, TALER_MERCHANTDB_WebhooksCallback cb, void *cb_cls); /** * Lookup details about a particular webhook. * * @param cls closure * @param instance_id instance to lookup webhook for * @param webhook_id webhook to lookup * @param[out] wb set to the webhook details on success, can be NULL * (in that case we only want to check if the webhook exists) * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_webhook)(void *cls, const char *instance_id, const char *webhook_id, struct TALER_MERCHANTDB_WebhookDetails *wb); /** * Delete information about a webhook. * * @param cls closure * @param instance_id instance to delete webhook of * @param webhook_id webhook to delete * @return DB status code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS * if webhook unknown. */ enum GNUNET_DB_QueryStatus (*delete_webhook)(void *cls, const char *instance_id, const char *webhook_id); /** * Insert details about a particular webhook. * * @param cls closure * @param instance_id instance to insert webhook for * @param webhook_id webhook identifier of webhook to insert * @param wb the webhook details to insert * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_webhook)(void *cls, const char *instance_id, const char *webhook_id, const struct TALER_MERCHANTDB_WebhookDetails *wb); /** * Update details about a particular webhook. * * @param cls closure * @param instance_id instance to update webhook for * @param webhook_id webhook to update * @param wb update to the webhook details on success, can be NULL * (in that case we only want to check if the webhook exists) * @return database result code, #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the webhook * does not yet exist. */ enum GNUNET_DB_QueryStatus (*update_webhook)(void *cls, const char *instance_id, const char *webhook_id, const struct TALER_MERCHANTDB_WebhookDetails *wb); /** * Lookup webhook by event * * @param cls closure * @param instance_id instance to lookup webhook for * @param event_type event that we need to put in the pending webhook * @param[out] cb set to the webhook details on success * @param cb_cls callback closure * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_webhook_by_event)(void *cls, const char *instance_id, const char *event_type, TALER_MERCHANTDB_WebhookDetailCallback cb, void *cb_cls); /** * Insert webhook in the pending webhook. * * @param cls closure * @param instance_id instance to insert webhook for * @param webhook_serial webhook to insert in the pending webhook * @param url to make the request to * @param http_method for the webhook * @param header of the webhook * @param body of the webhook * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_pending_webhook)(void *cls, const char *instance_id, uint64_t webhook_serial, const char *url, const char *http_method, const char *header, const char *body); /** * Lookup the webhook that need to be send in priority. These webhooks are not successfully * send. * * @param cls closure * @param cb pending webhook callback * @param cb_cls callback closure */ // WHERE next_attempt <= now ORDER BY next_attempt ASC enum GNUNET_DB_QueryStatus (*lookup_pending_webhooks)(void *cls, TALER_MERCHANTDB_PendingWebhooksCallback cb, void *cb_cls); /** * Lookup future webhook in the pending webhook that need to be send. * With that we can know how long the system can 'sleep'. * * @param cls closure * @param cb pending webhook callback * @param cb_cls callback closure */ // ORDER BY next_attempt ASC LIMIT 1 enum GNUNET_DB_QueryStatus (*lookup_future_webhook)(void *cls, TALER_MERCHANTDB_PendingWebhooksCallback cb, void *cb_cls); /** * Lookup all the webhooks in the pending webhook. * Use by the administrator * * @param cls closure * @param instance_id to lookup webhooks for this instance particularly * @param min_row to see the list of the pending webhook that it is started with this minimum row. * @param max_results to see the list of the pending webhook that it is end with this max results. * @param cb pending webhook callback * @param cb_cls callback closure */ // WHERE webhook_pending_serial > min_row ORDER BY webhook_pending_serial ASC LIMIT max_results enum GNUNET_DB_QueryStatus (*lookup_all_webhooks)(void *cls, const char *instance_id, uint64_t min_row, uint32_t max_results, TALER_MERCHANTDB_PendingWebhooksCallback cb, void *cb_cls); /** * Update the pending webhook. It is use if the webhook can't be send. * * @param cls closure * @param webhook_serial webhook that need to be update * @param next_attempt when we should make the next request to the webhook * @return database result code */ enum GNUNET_DB_QueryStatus (*update_pending_webhook)(void *cls, uint64_t webhook_pending_serial, struct GNUNET_TIME_Absolute next_attempt); // maybe add: http status of failure? /** * Delete a webhook in the pending webhook after the * webhook was completed successfully. * * @param cls closure * @param webhook_serial webhook that need to be delete in the pending webhook * @return database result code */ enum GNUNET_DB_QueryStatus (*delete_pending_webhook)(void *cls, uint64_t webhook_pending_serial); /** * Retrieve exchange's keys from the database. * * @param cls plugin closure * @param exchange_url base URL of the exchange * @param[out] keys set to the keys of the exchange * @return transaction status */ enum GNUNET_DB_QueryStatus (*select_exchange_keys)(void *cls, const char *exchange_url, struct TALER_EXCHANGE_Keys **keys); /** * Insert or update @a keys into the database. * * @param cls plugin closure * @param keys data to store * @return transaction status */ enum GNUNET_DB_QueryStatus (*insert_exchange_keys)(void *cls, const struct TALER_EXCHANGE_Keys *keys); /** * Lookup all of the token families the given instance has configured. * * @param cls closure * @param instance_id instance to lookup token families for * @param cb function to call on all token families found * @param cb_cls closure for @a cb * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_token_families)(void *cls, const char *instance_id, TALER_MERCHANTDB_TokenFamiliesCallback cb, void *cb_cls); /** * Lookup details about a particular token family. * * @param cls closure * @param instance_id instance to lookup token family for * @param token_family_slug token family to lookup * @param[out] details set to the token family details on success, can be NULL * (in that case we only want to check if the token family exists) * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_token_family)(void *cls, const char *instance_id, const char *token_family_slug, struct TALER_MERCHANTDB_TokenFamilyDetails *details); /** * Delete information about a token family. * * @param cls closure * @param instance_id instance to delete token family of * @param token_family_slug slug of token family to delete * @return database result code */ enum GNUNET_DB_QueryStatus (*delete_token_family)(void *cls, const char *instance_id, const char *token_family_slug); /** * Update details about a particular token family. * * @param cls closure * @param instance_id instance to update token family for * @param token_family_slug slug of token family to update * @param details set to the updated token family on success, can be NULL * (in that case we only want to check if the token family exists) * @return database result code */ enum GNUNET_DB_QueryStatus (*update_token_family)( void *cls, const char *instance_id, const char *token_family_slug, const struct TALER_MERCHANTDB_TokenFamilyDetails *details); /** * Insert details about a particular token family. * * @param cls closure * @param instance_id instance to insert token family for * @param token_family_slug slug of token family to insert * @param details the token family details to insert * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_token_family)( void *cls, const char *instance_id, const char *token_family_slug, const struct TALER_MERCHANTDB_TokenFamilyDetails *details); /** * Lookup details about a particular token family key. * * @param cls closure * @param instance_id instance to lookup token family key for * @param token_family_slug slug of token family to lookup * @param min_valid_after lower bound of the start of the key validation period * @param max_valid_after upper bound of the start of the key validation period * @param[out] details set to the token family key details on success, can be NULL * (in that case we only want to check if the token family key exists) * @return database result code */ enum GNUNET_DB_QueryStatus (*lookup_token_family_key)( void *cls, const char *instance_id, const char *token_family_slug, struct GNUNET_TIME_Timestamp min_valid_after, struct GNUNET_TIME_Timestamp max_valid_after, struct TALER_MERCHANTDB_TokenFamilyKeyDetails *details); /** * Insert details a key pair for a token family. * * @param cls closure * @param token_family_slug slug of token family to insert the key pair for * @param pub token family public key * @param priv token family private key * @param valid_after start of the key validation period * @param valid_before end of the key validation period * @return database result code */ enum GNUNET_DB_QueryStatus (*insert_token_family_key)( void *cls, const char *token_family_slug, const struct TALER_TokenIssuePublicKeyP *pub, const struct TALER_TokenIssuePrivateKeyP *priv, struct GNUNET_TIME_Timestamp valid_after, struct GNUNET_TIME_Timestamp valid_before); /** * Lookup deposits that are finished and awaiting a wire transfer. * * @param cls closure * @param exchange_url exchange to filter deposits by * @param limit maximum number of deposits to return * @param allow_future true to allow deposits with wire deadline in the future * @param cb function to call with deposit data * @param cb_cls closure for @a cb * @return transaction status */ enum GNUNET_DB_QueryStatus (*lookup_pending_deposits)( void *cls, const char *exchange_url, uint64_t limit, bool allow_future, TALER_MERCHANTDB_PendingDepositsCallback cb, void *cb_cls); /** * Update the deposit confirmation status associated with * the given @a deposit_serial. * * @param cls closure * @param deposit_serial deposit to update status for * @param wire_pending should we keep checking for the wire status with the exchange? * @param future_retry when should we ask the exchange again * @param retry_backoff current value for the retry backoff * @param emsg error message to record * @return database result code */ enum GNUNET_DB_QueryStatus (*update_deposit_confirmation_status)( void *cls, uint64_t deposit_serial, bool wire_pending, struct GNUNET_TIME_Timestamp future_retry, struct GNUNET_TIME_Relative retry_backoff, const char *emsg); }; #endif