/*
This file is part of TALER
Copyright (C) 2014-2020 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 include/taler_merchantdb_plugin.h
* @brief database access for the merchant
* @author Florian Dold
* @author Christian Grothoff
*/
#ifndef TALER_MERCHANTDB_PLUGIN_H
#define TALER_MERCHANTDB_PLUGIN_H
#include
#include
#include
/**
* Handle to interact with the database.
*/
struct TALER_MERCHANTDB_Plugin;
/**
* Details about a wire account of the merchant.
*/
struct TALER_MERCHANTDB_AccountDetails
{
/**
* Hash of the wire details (@e payto_uri and @e salt).
*/
struct GNUNET_HashCode h_wire;
/**
* Salt value used for hashing @e payto_uri.
*/
struct GNUNET_HashCode salt;
/**
* Actual account address as a payto://-URI.
*/
const char *payto_uri;
/**
* Is the account set for active use in new contracts?
*/
bool active;
};
/**
* General settings for an instance.
*/
struct TALER_MERCHANTDB_InstanceSettings
{
/**
* prefix for the instance under "/instances/"
*/
char *id;
/**
* legal name of the instance
*/
char *name;
/**
* Address of the business
*/
json_t *address;
/**
* jurisdiction of the business
*/
json_t *jurisdiction;
/**
* Default max deposit fee that the merchant is willing to
* pay; if deposit costs more, then the customer will cover
* the difference.
*/
struct TALER_Amount default_max_deposit_fee;
/**
* Default maximum wire fee to assume, unless stated differently in the
* proposal already.
*/
struct TALER_Amount default_max_wire_fee;
/**
* Default factor for wire fee amortization.
*/
uint32_t default_wire_fee_amortization;
/**
* 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 accounts_length length of the @a accounts array
* @param accounts list of accounts of the merchant
*/
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,
unsigned int accounts_length,
const struct TALER_MERCHANTDB_AccountDetails accounts[]);
/**
* Typically called by `lookup_products`.
*
* @param cls a `json_t *` JSON array to build
* @param product_id ID of the product
*/
typedef void
(*TALER_MERCHANTDB_ProductsCallback)(void *cls,
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;
/**
* 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;
/**
* Base64-encoded product image, or an empty string.
*/
json_t *image;
/**
* 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_Absolute next_restock;
};
/**
* Possible values for a binary filter.
*/
enum TALER_MERCHANTDB_YesNoAll
{
/**
* If condition is yes.
*/
TALER_MERCHANTDB_YNA_YES = 1,
/**
* If condition is no.
*/
TALER_MERCHANTDB_YNA_NO = 2,
/**
* Condition disabled.
*/
TALER_MERCHANTDB_YNA_ALL = 3
};
/**
* Filter preferences.
*/
struct TALER_MERCHANTDB_OrderFilter
{
/**
* Filter by payment status.
*/
enum TALER_MERCHANTDB_YesNoAll paid;
/**
* Filter by refund status.
*/
enum TALER_MERCHANTDB_YesNoAll refunded;
/**
* Filter by wire transfer status.
*/
enum TALER_MERCHANTDB_YesNoAll wired;
/**
* Filter orders by date, exact meaning depends on @e delta.
*/
struct GNUNET_TIME_Absolute 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_Absolute 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
* @param wire_fee wire fee the exchange charges
*/
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,
const struct TALER_Amount *wire_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);
/**
* Results from trying to increase a refund.
*/
enum TALER_MERCHANTDB_RefundStatus
{
/**
* 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
};
/* **************** OLD: ******************** */
/**
* Typically called by `find_contract_terms_by_date`.
*
* @param cls closure
* @param order_id order id
* @param row_id serial numer of the transaction in the table,
* @param contract_terms proposal data related to order id
*/
typedef void
(*TALER_MERCHANTDB_ProposalDataCallback)(void *cls,
const char *order_id,
uint64_t row_id,
const json_t *contract_terms);
/**
* Function called with information about a transaction.
*
* @param cls closure
* @param merchant_pub merchant's public key
* @param h_contract_terms proposal data's hashcode
* @param h_wire hash of our wire details
* @param timestamp time of the confirmation
* @param refund refund deadline
* @param total_amount total amount we receive for the contract after fees
*/
typedef void
(*TALER_MERCHANTDB_TransactionCallback)(
void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct GNUNET_HashCode *h_contract_terms,
const struct GNUNET_HashCode *h_wire,
struct GNUNET_TIME_Absolute timestamp,
struct GNUNET_TIME_Absolute refund,
const struct TALER_Amount *total_amount);
/**
* Function called with information about a coin that was deposited.
*
* @param cls closure
* @param h_contract_terms proposal data's hashcode
* @param coin_pub public key of the coin
* @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 exchange_proof proof from exchange that coin was accepted,
* matches the `interface DepositSuccess` of the documentation.
*/
typedef void
(*TALER_MERCHANTDB_CoinDepositCallback)(
void *cls,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
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 json_t *exchange_proof);
/**
* Information about the wire transfer corresponding to
* a deposit operation. Note that it is in theory possible
* that we have a @a h_contract_terms and @a coin_pub in the
* result that do not match a deposit that we know about,
* for example because someone else deposited funds into
* our account.
*
* @param cls closure
* @param h_contract_terms hashcode of the proposal data
* @param coin_pub public key of the coin
* @param wtid identifier of the wire transfer in which the exchange
* send us the money for the coin deposit
* @param execution_time when was the wire transfer executed?
* @param exchange_proof proof from exchange about what the deposit was for
* NULL if we have not asked for this signature
*/
typedef void
(*TALER_MERCHANTDB_TransferCallback)(
void *cls,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_WireTransferIdentifierRawP *wtid,
struct GNUNET_TIME_Absolute execution_time,
const json_t *exchange_proof);
/**
* Function called with information about a wire transfer identifier.
*
* @param cls closure
* @param proof proof from exchange about what the wire transfer was for
*/
typedef void
(*TALER_MERCHANTDB_ProofCallback)(void *cls,
const json_t *proof);
/**
* Function called with information about a refund.
*
* @param cls closure
* @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 refund_fee cost of this refund operation
*/
typedef void
(*TALER_MERCHANTDB_CoinRefundCallback)(
void *cls,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const char *exchange_url,
uint64_t rtransaction_id,
const char *reason,
const struct TALER_Amount *refund_amount,
const struct TALER_Amount *refund_fee);
/**
* 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;
/**
* Drop merchant tables. Used for testcases.
*
* @param cls closure
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
int
(*drop_tables) (void *cls);
/**
* Do a pre-flight check that we are not in an uncommitted transaction.
* If we are, try to commit the previous transaction and output a warning.
* 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
*/
int
(*start) (void *cls,
const char *name);
/**
* Roll back the current transaction of a database connection.
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @return #GNUNET_OK on success
*/
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 code
*/
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);
/**
* 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);
/**
* Insert information about an instance's account into our database.
*
* @param cls closure
* @param id identifier of the instance
* @param account_details details about the account
* @return database result code
*/
enum GNUNET_DB_QueryStatus
(*insert_account)(
void *cls,
const char *id,
const struct TALER_MERCHANTDB_AccountDetails *account_details);
/**
* 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);
/**
* Set an instance's account in our database to "inactive".
*
* @param cls closure
* @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 struct GNUNET_HashCode *h_wire);
/**
* Lookup all of the products the given instance has configured.
*
* @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_products)(void *cls,
const char *instance_id,
TALER_MERCHANTDB_ProductsCallback 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)
* @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);
/**
* 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
* @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);
/**
* 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 set to the product details on success, can be NULL
* (in that case we only want to check if the product exists);
* total_sold in @a pd is ignored, total_lost must not
* exceed total_stock minus the existing total_sold;
* total_sold and total_stock must be larger or equal to
* the existing value;
* @return database result code, #GNUNET_DB_SUCCESS_NO_RESULTS if the
* non-decreasing constraints are not met *or* if the product
* does not yet exist.
*/
enum GNUNET_DB_QueryStatus
(*update_product)(void *cls,
const char *instance_id,
const char *product_id,
const struct TALER_MERCHANTDB_ProductDetails *pd);
/**
* 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_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,
uint32_t quantity,
struct GNUNET_TIME_Absolute expiration_time);
/**
* 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
* @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);
/**
* 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] 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,
json_t **contract_terms);
/**
* 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 pay_deadline how long does the customer have to pay for the order
* @param contract_terms proposal data to store
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*insert_order)(void *cls,
const char *instance_id,
const char *order_id,
struct GNUNET_TIME_Absolute pay_deadline,
const json_t *contract_terms);
/**
* 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,
uint32_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
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*lookup_contract_terms)(void *cls,
const char *instance_id,
const char *order_id,
json_t **contract_terms);
/**
* 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 contract_terms contract to store
* @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);
/**
* 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 GNUNET_HashCode *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_Absolute start_date,
struct GNUNET_TIME_Absolute expire_date,
struct GNUNET_TIME_Absolute end_date,
const struct TALER_MasterSignatureP *master_sig);
/**
* Insert payment confirmation from the exchange into the database.
*
* @param cls closure
* @param instance_id instance to lookup deposits for
* @param h_contract_terms proposal data's hashcode
* @param coin_pub public key of the coin
* @param exchange_url URL of the exchange that issued @a coin_pub
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
* @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 signgin key that was used for @a exchange_sig
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*insert_deposit)(void *cls,
const char *instance_id,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
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 GNUNET_HashCode *h_wire,
const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_ExchangePublicKeyP *exchange_pub);
/**
* 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 GNUNET_HashCode *h_contract_terms,
TALER_MERCHANTDB_RefundCallback rc,
void *rc_cls);
/**
* Mark contract as paid and store the current @a session_id
* for which the contract was paid.
*
* @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, can be NULL
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*mark_contract_paid)(void *cls,
const char *instance_id,
const struct GNUNET_HashCode *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 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 GNUNET_HashCode *h_contract_terms,
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 GNUNET_HashCode *h_contract_terms,
bool *paid);
/**
* 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 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,
const char *reason);
/* ****************** OLD API ******************** */
/**
* Store the order ID that was used to pay for a resource within a session.
*
* @param cls closure
* @param session_id session id
* @param fulfillment_url URL that canonically identifies the resource
* being paid for
* @param order_id the order ID that was used when paying for the resource URL
* @param merchant_pub public key of the merchant, identifying the instance
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*insert_session_info)(void *cls,
const char *session_id,
const char *fulfillment_url,
const char *order_id,
const struct TALER_MerchantPublicKeyP *merchant_pub);
/**
* Retrieve the order ID that was used to pay for a resource within a session.
*
* @param cls closure
* @param[out] order_id location to store the order ID that was used when
* paying for the resource URL
* @param session_id session id
* @param fulfillment_url URL that canonically identifies the resource
* being paid for
* @param merchant_pub public key of the merchant, identifying the instance
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_session_info)(void *cls,
char **order_id,
const char *session_id,
const char *fulfillment_url,
const struct TALER_MerchantPublicKeyP *merchant_pub);
/**
* Retrieve proposal data given its hashcode
*
* @param cls closure
* @param[out] contract_terms where to store the result
* @param h_contract_terms hashcode used to lookup.
* @param merchant_pub instance's public key.
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_contract_terms_from_hash)(
void *cls,
json_t **contract_terms,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_MerchantPublicKeyP *merchant_pub);
/**
* Retrieve paid contract terms data given its hashcode.
*
* @param cls closure
* @param[out] contract_terms where to store the result
* @param h_contract_terms hashcode used to lookup.
* @param merchant_pub instance's public key.
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_paid_contract_terms_from_hash)(
void *cls,
json_t **contract_terms,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_MerchantPublicKeyP *merchant_pub);
/**
* Return proposals whose timestamps are younger than `date`.
* Among those proposals, only those ones being between the
* start-th and (start-nrows)-th record are returned. The rows
* are sorted having the youngest first.
*
* @param cls our plugin handle.
* @param date only results younger than this date are returned.
* @param merchant_pub instance's public key; only rows related to this
* instance are returned.
* @param start only rows with serial id less than start are returned.
* @param nrows only nrows rows are returned.
* @param past if set to #GNUNET_YES, retrieves rows older than `date`.
* @param ascending if GNUNET_YES, then results will be sorted with youngest first.
* This is typically used to show live updates on the merchant's backoffice
* @param cb function to call with transaction data, can be NULL.
* @param cb_cls closure for @a cb
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_contract_terms_by_date_and_range)(
void *cls,
struct GNUNET_TIME_Absolute date,
const struct TALER_MerchantPublicKeyP *merchant_pub,
uint64_t start,
uint64_t nrows,
int past,
unsigned int ascending,
TALER_MERCHANTDB_ProposalDataCallback cb,
void *cb_cls);
/**
* Lookup for a proposal, respecting the signature used by the
* /history's db methods.
*
* @param cls db plugin handle
* @param order_id order id used to search for the proposal data
* @param merchant_pub public key of the merchant using this method
* @param cb the callback
* @param cb_cls closure to pass to @a cb
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_contract_terms_history)(
void *cls,
const char *order_id,
const struct TALER_MerchantPublicKeyP *merchant_pub,
TALER_MERCHANTDB_ProposalDataCallback cb,
void *cb_cls);
/**
* Return proposals whose timestamp are older than `date`.
* The rows are sorted having the youngest first.*
*
* @param cls our plugin handle.
* @param date only results older than this date are returned.
* @param merchant_pub instance's public key; only rows related to this
* instance are returned.
* @param nrows only nrows rows are returned.
* @param cb function to call with transaction data, can be NULL.
* @param cb_cls closure for @a cb
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_contract_terms_by_date)(
void *cls,
struct GNUNET_TIME_Absolute date,
const struct TALER_MerchantPublicKeyP *merchant_pub,
uint64_t nrows,
TALER_MERCHANTDB_ProposalDataCallback cb,
void *cb_cls);
/**
* Insert mapping of @a coin_pub and @a h_contract_terms to
* corresponding @a wtid.
*
* @param cls closure
* @param h_contract_terms proposal data's hashcode
* @param coin_pub public key of the coin
* @param wtid identifier of the wire transfer in which the exchange
* send us the money for the coin deposit
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*store_coin_to_transfer)(
void *cls,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_WireTransferIdentifierRawP *wtid);
/**
* Insert wire transfer confirmation from the exchange into the database.
*
* @param cls closure
* @param exchange_url from which exchange did we get the @a exchange_proof
* @param wtid identifier of the wire transfer
* @param execution_time when was @a wtid executed
* @param signkey_pub public key used by the exchange for @a exchange_proof
* @param exchange_proof proof from exchange about what the deposit was for
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*store_transfer_to_proof)(
void *cls,
const char *exchange_url,
const struct TALER_WireTransferIdentifierRawP *wtid,
struct GNUNET_TIME_Absolute execution_time,
const struct TALER_ExchangePublicKeyP *signkey_pub,
const json_t *exchange_proof);
/**
* Store information about wire fees charged by an exchange,
* including signature (so we have proof).
*
* @param cls closure
* @param exchange_pub public key of the exchange
* @param h_wire_method hash of wire method
* @param wire_fee wire fee charged
* @param closing_fee closing fee charged (irrelevant for us,
* but needed to check signature)
* @param start_date start of fee being used
* @param end_date end of fee being used
* @param exchange_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 *exchange_pub,
const struct GNUNET_HashCode *h_wire_method,
const struct TALER_Amount *wire_fee,
const struct TALER_Amount *closing_fee,
struct GNUNET_TIME_Absolute start_date,
struct GNUNET_TIME_Absolute end_date,
const struct TALER_MasterSignatureP *exchange_sig);
/**
* Lookup information about coin payments by h_contract_terms and coin.
*
* @param cls closure
* @param h_contract_terms proposal data's hashcode
* @param merchant_pub merchant's public key. It's AND'd with @a h_contract_terms
* in order to find the result.
* @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
(*find_payments_by_hash_and_coin)(
void *cls,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
TALER_MERCHANTDB_CoinDepositCallback cb,
void *cb_cls);
/**
* Lookup information about a transfer by @a h_contract_terms. Note
* that in theory there could be multiple wire transfers for a
* single @a h_contract_terms, as the transaction may have involved
* multiple coins and the coins may be spread over different wire
* transfers.
*
* @param cls closure
* @param h_contract_terms proposal data's hashcode
* @param cb function to call with transfer data
* @param cb_cls closure for @a cb
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_transfers_by_hash)(void *cls,
const struct GNUNET_HashCode *h_contract_terms,
TALER_MERCHANTDB_TransferCallback cb,
void *cb_cls);
/**
* Lookup information about a coin deposits by @a wtid.
*
* @param cls closure
* @param wtid wire transfer identifier to find matching transactions for
* @param cb function to call with payment data
* @param cb_cls closure for @a cb
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_deposits_by_wtid)(void *cls,
const struct TALER_WireTransferIdentifierRawP *wtid,
TALER_MERCHANTDB_CoinDepositCallback cb,
void *cb_cls);
/**
* Lookup proof information about a wire transfer.
*
* @param cls closure
* @param exchange_url from which exchange are we looking for proof
* @param wtid wire transfer identifier for the search
* @param cb function to call with proof data
* @param cb_cls closure for @a cb
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*find_proof_by_wtid)(void *cls,
const char *exchange_url,
const struct TALER_WireTransferIdentifierRawP *wtid,
TALER_MERCHANTDB_ProofCallback cb,
void *cb_cls);
/**
* Obtain information about wire fees charged by an exchange,
* including signature (so we have proof).
*
* @param cls closure
* @param exchange_pub 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] wire_fee wire fee charged
* @param[out] closing_fee closing fee charged (irrelevant for us,
* but needed to check signature)
* @param[out] start_date start of fee being used
* @param[out] end_date end of fee being used
* @param[out] exchange_sig signature of exchange over fee structure
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*lookup_wire_fee)(void *cls,
const struct TALER_MasterPublicKeyP *exchange_pub,
const struct GNUNET_HashCode *h_wire_method,
struct GNUNET_TIME_Absolute contract_date,
struct TALER_Amount *wire_fee,
struct TALER_Amount *closing_fee,
struct GNUNET_TIME_Absolute *start_date,
struct GNUNET_TIME_Absolute *end_date,
struct TALER_MasterSignatureP *exchange_sig);
/**
* Obtain refund proofs associated with a refund operation on a
* coin.
*
* @param cls closure, typically a connection to the db
* @param merchant_pub public key of the merchant instance
* @param h_contract_terms hash code of the contract
* @param coin_pub public key of the coin
* @param rtransaction_id identificator of the refund
* @param[out] exchange_pub public key of the exchange affirming the refund
* @param[out] exchange_sig signature of the exchange affirming the refund
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*get_refund_proof)(
void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
struct TALER_ExchangePublicKeyP *exchange_pub,
struct TALER_ExchangeSignatureP *exchange_sig);
/**
* Store refund proofs associated with a refund operation on a
* coin.
*
* @param cls closure, typically a connection to the db
* @param merchant_pub public key of the merchant instance
* @param h_contract_terms hash code of the contract
* @param coin_pub public key of the coin
* @param rtransaction_id identificator of the refund
* @param exchange_pub public key of the exchange affirming the refund
* @param exchange_sig signature of the exchange affirming the refund
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*put_refund_proof)(
void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct GNUNET_HashCode *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
uint64_t rtransaction_id,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_ExchangeSignatureP *exchange_sig);
/**
* Add @a credit to a reserve to be used for tipping. Note that
* this function does not actually perform any wire transfers to
* credit the reserve, it merely tells the merchant backend that
* a reserve was topped up. This has to happen before tips can be
* authorized.
*
* @param cls closure, typically a connection to the db
* @param reserve_priv which reserve is topped up or created
* @param credit_uuid unique identifier for the credit operation
* @param credit how much money was added to the reserve
* @param expiration when does the reserve expire?
* @return transaction status, usually
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success
* #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a credit_uuid already known
*/
enum GNUNET_DB_QueryStatus
(*enable_tip_reserve_TR)(void *cls,
const struct TALER_ReservePrivateKeyP *reserve_priv,
const struct GNUNET_HashCode *credit_uuid,
const struct TALER_Amount *credit,
struct GNUNET_TIME_Absolute expiration);
/**
* Authorize a tip over @a amount from reserve @a reserve_priv. Remember
* the authorization under @a tip_id for later, together with the
* @a justification.
*
* @param cls closure, typically a connection to the db
* @param justification why was the tip approved
* @param extra extra data that will be given to the customer's wallet
* @param amount how high is the tip (with fees)
* @param reserve_priv which reserve is debited
* @param exchange_url which exchange manages the tip
* @param[out] expiration set to when the tip expires
* @param[out] tip_id set to the unique ID for the tip
* @return transaction status,
* #TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED if the reserve is known but has expired
* #TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN if the reserve is not known
* #TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS if the reserve has insufficient funds left
* #TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR on hard DB errors
* #TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR on soft DB errors (client should retry)
* #TALER_EC_NONE upon success
*/
enum TALER_ErrorCode
(*authorize_tip_TR)(void *cls,
const char *justification,
const json_t *extra,
const struct TALER_Amount *amount,
const struct TALER_ReservePrivateKeyP *reserve_priv,
const char *exchange_url,
struct GNUNET_TIME_Absolute *expiration,
struct GNUNET_HashCode *tip_id);
/**
* Get the total amount of authorized tips for a tipping reserve.
*
* @param cls closure, typically a connection to the db
* @param reserve_priv which reserve to check
* @param[out] authorzed_amount amount we've authorized so far for tips
* @return transaction status, usually
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success
* #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the reserve_priv
* does not identify a known tipping reserve
*/
enum GNUNET_DB_QueryStatus
(*get_authorized_tip_amount)(void *cls,
const struct
TALER_ReservePrivateKeyP *reserve_priv,
struct TALER_Amount *authorized_amount);
/**
* Find out tip authorization details associated with @a tip_id
*
* @param cls closure, typically a connection to the d
* @param tip_id the unique ID for the tip
* @param[out] exchange_url set to the URL of the exchange (unless NULL)
* @param[out] extra extra data to pass to the wallet
* @param[out] amount set to the authorized amount (unless NULL)
* @param[out] amount_left set to the amount left (unless NULL)
* @param[out] timestamp set to the timestamp of the tip authorization (unless NULL)
* @return transaction status, usually
* #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT for success
* #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if @a credit_uuid already known
*/
enum GNUNET_DB_QueryStatus
(*lookup_tip_by_id)(void *cls,
const struct GNUNET_HashCode *tip_id,
char **exchange_url,
json_t **extra,
struct TALER_Amount *amount,
struct TALER_Amount *amount_left,
struct GNUNET_TIME_Absolute *timestamp);
/**
* Pickup a tip over @a amount using pickup id @a pickup_id.
*
* @param cls closure, typically a connection to the db
* @param amount how high is the amount picked up (with fees)
* @param tip_id the unique ID from the tip authorization
* @param pickup_id the unique ID identifying the pick up operation
* (to allow replays, hash over the coin envelope and denomination key)
* @param[out] reserve_priv which reserve key to use to sign
* @return taler error code
* #TALER_EC_TIP_PICKUP_ID_UNKNOWN if @a tip_id is unknown
* #TALER_EC_TIP_PICKUP_NO_FUNDS if @a tip_id has insufficient funds left
* #TALER_EC_TIP_PICKUP_DB_ERROR on database errors
* #TALER_EC_NONE upon success (@a reserve_priv was set)
*/
enum TALER_ErrorCode
(*pickup_tip_TR)(void *cls,
const struct TALER_Amount *amount,
const struct GNUNET_HashCode *tip_id,
const struct GNUNET_HashCode *pickup_id,
struct TALER_ReservePrivateKeyP *reserve_priv);
};
#endif