commit 3e17cd9c65f071514cce08726f1d191bef90b083
parent 80e27a8c6b13b74887ab668397c68b619305cf08
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 22 Jul 2026 03:18:24 +0200
merchantdb: more renaming
Diffstat:
91 files changed, 2939 insertions(+), 2938 deletions(-)
diff --git a/src/backend/taler-merchant-donaukeyupdate.c b/src/backend/taler-merchant-donaukeyupdate.c
@@ -33,7 +33,7 @@
#include "merchant-database/iterate_all_donau_instances.h"
#include "merchant-database/get_donau_instance_by_serial.h"
#include "merchant-database/update_donau_instance.h"
-#include "merchant-database/upsert_donau_keys.h"
+#include "merchant-database/insert_donau_keys.h"
#include "merchant-database/event_listen.h"
#include "merchant-database/preflight.h"
#include "merchant-database/start.h"
@@ -339,7 +339,7 @@ insert_donau_keys_data (const struct DONAU_Keys *keys,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Inserting Donau keys into the database %s\n",
keys->donau_url);
- return TALER_MERCHANTDB_upsert_donau_keys (pg,
+ return TALER_MERCHANTDB_insert_donau_keys (pg,
keys,
first_retry);
}
diff --git a/src/backend/taler-merchant-exchangekeyupdate.c b/src/backend/taler-merchant-exchangekeyupdate.c
@@ -40,7 +40,7 @@ struct Exchange;
#include "merchant-database/event_listen.h"
#include "merchant-database/insert_exchange_account.h"
#include "merchant-database/get_exchange_keys.h"
-#include "merchant-database/store_wire_fee_by_exchange.h"
+#include "merchant-database/insert_wire_fee.h"
/**
* Maximum frequency for the exchange interaction.
@@ -450,7 +450,7 @@ insert_keys_data (const struct TALER_EXCHANGE_Keys *keys,
GNUNET_CRYPTO_hash (wire_method,
strlen (wire_method) + 1,
&h_wire_method);
- qs = TALER_MERCHANTDB_store_wire_fee_by_exchange (
+ qs = TALER_MERCHANTDB_insert_wire_fee (
pg,
&keys->master_pub,
&h_wire_method,
diff --git a/src/backend/taler-merchant-httpd_delete-management-instances-INSTANCE.c b/src/backend/taler-merchant-httpd_delete-management-instances-INSTANCE.c
@@ -23,9 +23,9 @@
#include <taler/taler_json_lib.h>
#include <taler/taler_dbevents.h>
#include "taler-merchant-httpd_mfa.h"
-#include "merchant-database/delete_instance_private_key.h"
+#include "merchant-database/update_to_instance_private_key_deleted.h"
#include "merchant-database/event_notify.h"
-#include "merchant-database/purge_instance.h"
+#include "merchant-database/delete_instance.h"
/**
* Handle a DELETE "/instances/$ID" request.
@@ -73,11 +73,11 @@ delete_instances_ID (struct TMH_HandlerContext *hc,
"yes"));
}
if (purge)
- qs = TALER_MERCHANTDB_purge_instance (TMH_db,
- mi->settings.id);
+ qs = TALER_MERCHANTDB_delete_instance (TMH_db,
+ mi->settings.id);
else
- qs = TALER_MERCHANTDB_delete_instance_private_key (TMH_db,
- mi->settings.id);
+ qs = TALER_MERCHANTDB_update_to_instance_private_key_deleted (TMH_db,
+ mi->settings.id);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
diff --git a/src/backend/taler-merchant-httpd_delete-private-accounts-H_WIRE.c b/src/backend/taler-merchant-httpd_delete-private-accounts-H_WIRE.c
@@ -23,7 +23,7 @@
#include <taler/taler_json_lib.h>
#include <taler/taler_dbevents.h>
#include "taler-merchant-httpd_mfa.h"
-#include "merchant-database/inactivate_account.h"
+#include "merchant-database/update_to_account_inactive.h"
#include "merchant-database/event_notify.h"
@@ -69,9 +69,9 @@ TMH_private_delete_account_ID (const struct TMH_RequestHandler *rh,
: MHD_NO;
}
}
- qs = TALER_MERCHANTDB_inactivate_account (TMH_db,
- mi->settings.id,
- &h_wire);
+ qs = TALER_MERCHANTDB_update_to_account_inactive (TMH_db,
+ mi->settings.id,
+ &h_wire);
switch (qs)
{
case GNUNET_DB_STATUS_HARD_ERROR:
diff --git a/src/backend/taler-merchant-httpd_get-private-orders-ORDER_ID.c b/src/backend/taler-merchant-httpd_get-private-orders-ORDER_ID.c
@@ -38,7 +38,7 @@
#include "merchant-database/get_order_by_fulfillment.h"
#include "merchant-database/iterate_refunds_detailed.h"
#include "merchant-database/iterate_transfer_details_by_order.h"
-#include "merchant-database/mark_order_wired.h"
+#include "merchant-database/update_to_contract_terms_wired.h"
#include "merchant-database/preflight.h"
#include "merchant-database/event_listen.h"
@@ -1681,8 +1681,8 @@ phase_check_local_transfers (struct GetOrderRequestContext *gorc)
{
/* expect_total <= gorc->deposits_total: good: we got the wire transfer */
gorc->wired = true;
- qs = TALER_MERCHANTDB_mark_order_wired (TMH_db,
- gorc->order_serial);
+ qs = TALER_MERCHANTDB_update_to_contract_terms_wired (TMH_db,
+ gorc->order_serial);
GNUNET_break (qs >= 0); /* just warn if transaction failed */
TMH_notify_order_change (hc->instance,
TMH_OSF_PAID
diff --git a/src/backend/taler-merchant-httpd_mfa.c b/src/backend/taler-merchant-httpd_mfa.c
@@ -25,7 +25,7 @@
#include "platform.h"
#include "taler-merchant-httpd.h"
#include "taler-merchant-httpd_mfa.h"
-#include "merchant-database/create_mfa_challenge.h"
+#include "merchant-database/insert_mfa_challenge.h"
#include "merchant-database/get_mfa_challenge.h"
@@ -272,7 +272,7 @@ mfa_challenge_start (
"%04llu-%04llu",
challenge_num / 10000,
challenge_num % 10000);
- qs = TALER_MERCHANTDB_create_mfa_challenge (TMH_db,
+ qs = TALER_MERCHANTDB_insert_mfa_challenge (TMH_db,
instance_name,
op,
&h_body,
diff --git a/src/backend/taler-merchant-httpd_post-challenge-ID-confirm.c b/src/backend/taler-merchant-httpd_post-challenge-ID-confirm.c
@@ -26,7 +26,7 @@
#include "taler-merchant-httpd.h"
#include "taler-merchant-httpd_mfa.h"
#include "taler-merchant-httpd_post-challenge-ID-confirm.h"
-#include "merchant-database/solve_mfa_challenge.h"
+#include "merchant-database/do_solve_mfa_challenge.h"
enum MHD_Result
@@ -91,14 +91,14 @@ TMH_post_challenge_ID_confirm (const struct TMH_RequestHandler *rh,
}
}
- qs = TALER_MERCHANTDB_solve_mfa_challenge (TMH_db,
- challenge_serial,
- &h_body,
- (NULL == xtan)
+ qs = TALER_MERCHANTDB_do_solve_mfa_challenge (TMH_db,
+ challenge_serial,
+ &h_body,
+ (NULL == xtan)
? tan
: xtan,
- &solved,
- &retry_counter);
+ &solved,
+ &retry_counter);
GNUNET_free (xtan);
switch (qs)
{
diff --git a/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-abort.c b/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-abort.c
@@ -34,7 +34,7 @@ struct RefundDetails;
#include "taler-merchant-httpd_post-orders-ORDER_ID-abort.h"
#include "merchant-database/iterate_deposits.h"
#include "merchant-database/get_order_status.h"
-#include "merchant-database/refund_coin.h"
+#include "merchant-database/insert_refund_by_coin.h"
#include "merchant-database/preflight.h"
#include "merchant-database/start.h"
#include "merchant-database/set_instance.h"
@@ -708,13 +708,13 @@ refund_coins (void *cls,
rdi->found_deposit = true;
rdi->amount_with_fee = *amount_with_fee;
/* Store refund in DB */
- qs = TALER_MERCHANTDB_refund_coin (TMH_db,
- ac->hc->instance->settings.id,
- &ac->h_contract_terms,
- now,
- coin_pub,
- /* justification */
- "incomplete abortment aborted");
+ qs = TALER_MERCHANTDB_insert_refund_by_coin (TMH_db,
+ ac->hc->instance->settings.id,
+ &ac->h_contract_terms,
+ now,
+ coin_pub,
+ /* justification */
+ "incomplete abortment aborted");
if (0 > qs)
{
/* Always report on hard error to enable diagnostics */
diff --git a/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c
@@ -52,7 +52,7 @@ struct ExchangeGroup;
#include <donau/donau_service.h>
#include <donau/donau_util.h>
#include <donau/donau_json_lib.h>
-#include "merchant-database/increment_money_pots.h"
+#include "merchant-database/update_money_pot_totals.h"
#include "merchant-database/insert_deposit.h"
#include "merchant-database/insert_deposit_confirmation.h"
#include "merchant-database/insert_issued_token.h"
@@ -66,7 +66,7 @@ struct ExchangeGroup;
#include "merchant-database/set_instance.h"
#include "merchant-database/iterate_spent_tokens_by_order.h"
#include "merchant-database/get_token_family_key.h"
-#include "merchant-database/mark_contract_paid.h"
+#include "merchant-database/update_to_contract_terms_paid.h"
#include "merchant-database/iterate_order_blinded_sigs.h"
#include "merchant-database/start.h"
#include "merchant-database/preflight.h"
@@ -3147,11 +3147,11 @@ phase_execute_pay_transaction (struct PayContext *pc)
{
enum GNUNET_DB_QueryStatus qs;
- qs = TALER_MERCHANTDB_mark_contract_paid (TMH_db,
- instance_id,
- &pc->check_contract.h_contract_terms,
- pc->parse_pay.session_id,
- pc->parse_wallet_data.choice_index);
+ qs = TALER_MERCHANTDB_update_to_contract_terms_paid (TMH_db,
+ instance_id,
+ &pc->check_contract.h_contract_terms,
+ pc->parse_pay.session_id,
+ pc->parse_wallet_data.choice_index);
if (qs < 0)
{
TALER_MERCHANTDB_rollback (TMH_db);
@@ -3176,7 +3176,7 @@ phase_execute_pay_transaction (struct PayContext *pc)
"Incrementing %u money pots by %s\n",
pc->compute_money_pots.num_pots,
TALER_amount2s (&pc->compute_money_pots.increments[0]));
- qs = TALER_MERCHANTDB_increment_money_pots (
+ qs = TALER_MERCHANTDB_update_money_pot_totals (
TMH_db,
instance_id,
pc->compute_money_pots.num_pots,
diff --git a/src/backend/taler-merchant-httpd_post-private-accounts.c b/src/backend/taler-merchant-httpd_post-private-accounts.c
@@ -30,7 +30,7 @@
#include <taler/taler_json_lib.h>
#include "taler-merchant-httpd_mfa.h"
#include <regex.h>
-#include "merchant-database/activate_account.h"
+#include "merchant-database/do_insert_account.h"
#include "merchant-database/iterate_accounts_by_instance.h"
#include "merchant-database/preflight.h"
@@ -404,12 +404,12 @@ TMH_private_post_account (const struct TMH_RequestHandler *rh,
bool conflict;
TALER_MERCHANTDB_preflight (TMH_db);
- qs = TALER_MERCHANTDB_activate_account (TMH_db,
- &ad,
- &h_wire,
- &salt,
- ¬_found,
- &conflict);
+ qs = TALER_MERCHANTDB_do_insert_account (TMH_db,
+ &ad,
+ &h_wire,
+ &salt,
+ ¬_found,
+ &conflict);
switch (qs)
{
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
diff --git a/src/backend/taler-merchant-httpd_post-private-orders-ORDER_ID-refund.c b/src/backend/taler-merchant-httpd_post-private-orders-ORDER_ID-refund.c
@@ -29,7 +29,7 @@
#include "taler-merchant-httpd_get-private-orders.h"
#include "taler-merchant-httpd_helper.h"
#include "taler-merchant-httpd_get-exchanges.h"
-#include "merchant-database/increase_refund.h"
+#include "merchant-database/do_increase_refund.h"
#include "merchant-database/get_contract_terms.h"
#include "merchant-database/get_order_summary.h"
#include "merchant-database/start.h"
@@ -306,13 +306,13 @@ TMH_private_post_orders_ID_refund (
TALER_EC_GENERIC_DB_START_FAILED,
NULL);
}
- rs = TALER_MERCHANTDB_increase_refund (TMH_db,
- hc->instance->settings.id,
- hc->infix,
- &refund,
- &get_refund_limit,
- NULL,
- reason);
+ rs = TALER_MERCHANTDB_do_increase_refund (TMH_db,
+ hc->instance->settings.id,
+ hc->infix,
+ &refund,
+ &get_refund_limit,
+ NULL,
+ reason);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"increase refund returned %d\n",
rs);
diff --git a/src/backend/taler-merchant-httpd_post-private-orders.c b/src/backend/taler-merchant-httpd_post-private-orders.c
@@ -51,7 +51,7 @@
#include "merchant-database/event_listen.h"
#include "merchant-database/event_notify.h"
#include "merchant-database/preflight.h"
-#include "merchant-database/expire_locks.h"
+#include "merchant-database/do_expire_locks.h"
#include "merchant-database/get_missing_money_pot.h"
#include "merchant-database/insert_order.h"
#include "merchant-database/insert_order_lock.h"
@@ -63,7 +63,7 @@
#include "merchant-database/iterate_token_family_keys.h"
#include "merchant-database/iterate_donau_instances_filtered.h"
#include "merchant-database/get_otp.h"
-#include "merchant-database/unlock_inventory.h"
+#include "merchant-database/delete_inventory_lock.h"
/**
@@ -1002,8 +1002,8 @@ execute_transaction (struct OrderContext *oc)
/* Migrate locks from UUIDs to new order: first release old locks */
for (unsigned int i = 0; i<oc->parse_request.uuids_length; i++)
{
- qs = TALER_MERCHANTDB_unlock_inventory (TMH_db,
- &oc->parse_request.uuids[i]);
+ qs = TALER_MERCHANTDB_delete_inventory_lock (TMH_db,
+ &oc->parse_request.uuids[i]);
if (qs < 0)
{
TALER_MERCHANTDB_rollback (TMH_db);
@@ -4054,7 +4054,7 @@ phase_parse_request (struct OrderContext *oc)
"Refund delay is %s\n",
GNUNET_TIME_relative2s (oc->parse_request.refund_delay,
false));
- TALER_MERCHANTDB_expire_locks (TMH_db);
+ TALER_MERCHANTDB_do_expire_locks (TMH_db);
if (NULL != otp_id)
{
struct TALER_MERCHANTDB_OtpDeviceDetails td;
diff --git a/src/backend/taler-merchant-httpd_post-private-products-PRODUCT_ID-lock.c b/src/backend/taler-merchant-httpd_post-private-products-PRODUCT_ID-lock.c
@@ -26,8 +26,8 @@
#include "taler-merchant-httpd_post-private-products-PRODUCT_ID-lock.h"
#include "taler-merchant-httpd_helper.h"
#include <taler/taler_json_lib.h>
-#include "merchant-database/expire_locks.h"
-#include "merchant-database/lock_product.h"
+#include "merchant-database/do_expire_locks.h"
+#include "merchant-database/insert_inventory_lock.h"
#include "merchant-database/get_product.h"
@@ -78,7 +78,7 @@ TMH_private_post_products_ID_lock (
}
TMH_uuid_from_string (uuids,
&uuid);
- TALER_MERCHANTDB_expire_locks (TMH_db);
+ TALER_MERCHANTDB_do_expire_locks (TMH_db);
{
struct TALER_MERCHANTDB_ProductDetails pd = { 0 };
size_t num_categories;
@@ -163,13 +163,13 @@ TMH_private_post_products_ID_lock (
}
}
quantity = normalized_quantity;
- qs = TALER_MERCHANTDB_lock_product (TMH_db,
- mi->settings.id,
- product_id,
- &uuid,
- quantity,
- normalized_quantity_frac,
- GNUNET_TIME_relative_to_timestamp (duration));
+ qs = TALER_MERCHANTDB_insert_inventory_lock (TMH_db,
+ mi->settings.id,
+ product_id,
+ &uuid,
+ quantity,
+ normalized_quantity_frac,
+ GNUNET_TIME_relative_to_timestamp (duration));
TALER_MERCHANTDB_product_details_free (&pd);
}
switch (qs)
diff --git a/src/backend/taler-merchant-reconciliation.c b/src/backend/taler-merchant-reconciliation.c
@@ -30,7 +30,7 @@ struct Inquiry;
#include "taler/taler_merchant_bank_lib.h"
#include "merchantdb_lib.h"
#include "merchantdb_lib.h"
-#include "merchant-database/finalize_transfer_status.h"
+#include "merchant-database/update_to_transfer_finalized.h"
#include "merchant-database/insert_transfer_details.h"
#include "merchant-database/iterate_deposits_by_contract_and_coin.h"
#include "merchant-database/get_wire_fee.h"
@@ -965,14 +965,14 @@ wire_transfer_cb (struct Inquiry *w,
{
enum GNUNET_DB_QueryStatus qs;
- qs = TALER_MERCHANTDB_finalize_transfer_status (pg,
- w->exchange->exchange_url,
- &w->wtid,
- &td->h_details,
- &td->total_amount,
- &td->wire_fee,
- &td->exchange_pub,
- &td->exchange_sig);
+ qs = TALER_MERCHANTDB_update_to_transfer_finalized (pg,
+ w->exchange->exchange_url,
+ &w->wtid,
+ &td->h_details,
+ &td->total_amount,
+ &td->wire_fee,
+ &td->exchange_pub,
+ &td->exchange_sig);
if (qs < 0)
{
GNUNET_break (0);
diff --git a/src/backenddb/activate_account.c b/src/backenddb/activate_account.c
@@ -1,80 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/activate_account.c
- * @brief Implementation of the activate_account function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/activate_account.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_activate_account (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const struct TALER_MERCHANTDB_AccountDetails *account_details,
- struct TALER_MerchantWireHashP *h_wire,
- struct TALER_WireSaltP *salt,
- bool *not_found,
- bool *conflict)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&account_details->h_wire),
- GNUNET_PQ_query_param_auto_from_type (&account_details->salt),
- GNUNET_PQ_query_param_string (account_details->payto_uri.full_payto),
- NULL ==account_details->credit_facade_url
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (account_details->credit_facade_url),
- NULL == account_details->credit_facade_credentials
- ? GNUNET_PQ_query_param_null ()
- : TALER_PQ_query_param_json (account_details->credit_facade_credentials),
- NULL == account_details->extra_wire_subject_metadata
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (
- account_details->extra_wire_subject_metadata),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("not_found",
- not_found),
- GNUNET_PQ_result_spec_bool ("conflict",
- conflict),
- GNUNET_PQ_result_spec_auto_from_type ("h_wire",
- h_wire),
- GNUNET_PQ_result_spec_auto_from_type ("salt",
- salt),
- GNUNET_PQ_result_spec_end
- };
-
- GNUNET_assert (account_details->active);
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (account_details->instance_id,
- pg->current_merchant_id));
- TMH_PQ_prepare_anon (pg,
- "SELECT "
- " out_h_wire AS h_wire"
- " ,out_salt AS salt"
- " ,out_conflict AS conflict"
- " ,out_not_found AS not_found"
- " FROM merchant_do_activate_account"
- " ($1,$2,$3,$4,$5,$6);");
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "",
- params,
- rs);
-}
diff --git a/src/backenddb/create_mfa_challenge.c b/src/backenddb/create_mfa_challenge.c
@@ -1,86 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/create_mfa_challenge.c
- * @brief Implementation of the create_mfa_challenge function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "taler/taler_merchant_util.h"
-#include "merchantdb_lib.h"
-#include "merchant-database/create_mfa_challenge.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_create_mfa_challenge (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_name,
- enum TALER_MERCHANT_MFA_CriticalOperation op,
- const struct TALER_MERCHANT_MFA_BodyHash *h_body,
- const struct TALER_MERCHANT_MFA_BodySalt *salt,
- const char *code,
- struct GNUNET_TIME_Absolute expiration_date,
- struct GNUNET_TIME_Absolute retransmission_date,
- enum TALER_MERCHANT_MFA_Channel tan_channel,
- const char *required_address,
- uint64_t *challenge_id)
-{
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
- const char *op_str = TALER_MERCHANT_MFA_co_to_string (op);
- const char *channel_str = TALER_MERCHANT_MFA_channel_to_string (tan_channel);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_body),
- GNUNET_PQ_query_param_auto_from_type (salt),
- GNUNET_PQ_query_param_string (op_str),
- GNUNET_PQ_query_param_string (code),
- GNUNET_PQ_query_param_absolute_time (&now), /* $5 */
- GNUNET_PQ_query_param_absolute_time (&expiration_date),
- GNUNET_PQ_query_param_absolute_time (&retransmission_date),
- GNUNET_PQ_query_param_string (channel_str),
- GNUNET_PQ_query_param_string (required_address), /* $9 */
- GNUNET_PQ_query_param_string (instance_name),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("challenge_id",
- challenge_id),
- GNUNET_PQ_result_spec_end
- };
-
- PREPARE (pg,
- "create_mfa_challenge",
- "INSERT INTO merchant.tan_challenges"
- " (h_body"
- " ,salt"
- " ,op"
- " ,code"
- " ,creation_date"
- " ,expiration_date"
- " ,retransmission_date"
- " ,retry_counter" /* always set to 3 */
- " ,tan_channel"
- " ,required_address"
- " ,instance_name)"
- " VALUES"
- " ($1, $2, $3, $4, $5, $6, $7, 3, $8, $9, $10)"
- " RETURNING challenge_id;");
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "create_mfa_challenge",
- params,
- rs);
-}
diff --git a/src/backenddb/delete_instance.c b/src/backenddb/delete_instance.c
@@ -0,0 +1,52 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/delete_instance.c
+ * @brief Implementation of the delete_instance function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/delete_instance.h"
+#include "helper.h"
+
+
+/**
+ * Purge an instance and all associated information from our database.
+ * Highly likely to cause undesired data loss. Use with caution.
+ *
+ * @param pg database context
+ * @param merchant_id identifier of the instance
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_delete_instance (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *merchant_id)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (merchant_id),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "purge_instance",
+ "DELETE FROM merchant.merchant_instances"
+ " WHERE merchant_id = $1");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "purge_instance",
+ params);
+}
diff --git a/src/backenddb/delete_instance_private_key.c b/src/backenddb/delete_instance_private_key.c
@@ -1,45 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/delete_instance_private_key.c
- * @brief Implementation of the delete_instance_private_key function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/delete_instance_private_key.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_delete_instance_private_key (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *merchant_id)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (merchant_id),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (pg,
- "delete_instance_private_key",
- "UPDATE merchant.merchant_instances"
- " SET merchant_priv = NULL"
- " WHERE merchant_id = $1");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "delete_instance_private_key",
- params);
-}
diff --git a/src/backenddb/delete_inventory_lock.c b/src/backenddb/delete_inventory_lock.c
@@ -0,0 +1,45 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/delete_inventory_lock.c
+ * @brief Implementation of the delete_inventory_lock function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/delete_inventory_lock.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_delete_inventory_lock (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const struct GNUNET_Uuid *uuid)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (uuid),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ TMH_PQ_prepare_anon (pg,
+ "DELETE"
+ " FROM merchant_inventory_locks"
+ " WHERE lock_uuid=$1");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ params);
+}
diff --git a/src/backenddb/do_expire_locks.c b/src/backenddb/do_expire_locks.c
@@ -0,0 +1,60 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/do_expire_locks.c
+ * @brief Implementation of the do_expire_locks function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/do_expire_locks.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_do_expire_locks (struct TALER_MERCHANTDB_PostgresContext *pg)
+{
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_end
+ };
+ uint64_t total;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("expire_locks",
+ &total),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ PREPARE (pg,
+ "expire_locks",
+ "SELECT expire_locks($1) "
+ " AS expire_locks");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "expire_locks",
+ params,
+ rs);
+ if (qs < 0)
+ {
+ GNUNET_break (0);
+ return qs;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Released %llu locks for the current instance\n",
+ (unsigned long long) total);
+ return (enum GNUNET_DB_QueryStatus) total;
+}
diff --git a/src/backenddb/expire_locks.sql b/src/backenddb/do_expire_locks.sql
diff --git a/src/backenddb/do_increase_refund.c b/src/backenddb/do_increase_refund.c
@@ -0,0 +1,740 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/do_increase_refund.c
+ * @brief Implementation of the do_increase_refund function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/do_increase_refund.h"
+#include "helper.h"
+
+
+/**
+ * Information about refund limits per exchange.
+ */
+struct ExchangeLimit
+{
+ /**
+ * Kept in a DLL.
+ */
+ struct ExchangeLimit *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct ExchangeLimit *prev;
+
+ /**
+ * Exchange the limit is about.
+ */
+ char *exchange_url;
+
+ /**
+ * Refund amount remaining at this exchange.
+ */
+ struct TALER_Amount remaining_refund_limit;
+
+};
+
+
+/**
+ * Closure for #process_refund_cb().
+ */
+struct FindRefundContext
+{
+
+ /**
+ * Plugin context.
+ */
+ struct TALER_MERCHANTDB_PostgresContext *pg;
+
+ /**
+ * Updated to reflect total amount refunded so far.
+ */
+ struct TALER_Amount refunded_amount;
+
+ /**
+ * Set to the largest refund transaction ID encountered.
+ */
+ uint64_t max_rtransaction_id;
+
+ /**
+ * Set to true on hard errors.
+ */
+ bool err;
+};
+
+
+/**
+ * Closure for #process_deposits_for_refund_cb().
+ */
+struct InsertRefundContext
+{
+ /**
+ * Used to provide a connection to the db
+ */
+ struct TALER_MERCHANTDB_PostgresContext *pg;
+
+ /**
+ * Head of DLL of per-exchange refund limits.
+ */
+ struct ExchangeLimit *el_head;
+
+ /**
+ * Tail of DLL of per-exchange refund limits.
+ */
+ struct ExchangeLimit *el_tail;
+
+ /**
+ * Amount to which increase the refund for this contract
+ */
+ const struct TALER_Amount *refund;
+
+ /**
+ * Human-readable reason behind this refund
+ */
+ const char *reason;
+
+ /**
+ * Function to call to determine per-exchange limits.
+ * NULL for no limits.
+ */
+ TALER_MERCHANTDB_OperationLimitCallback olc;
+
+ /**
+ * Closure for @e olc.
+ */
+ void *olc_cls;
+
+ /**
+ * Transaction status code.
+ */
+ enum TALER_MERCHANTDB_RefundStatus rs;
+
+ /**
+ * Did we have to cap refunds of any coin
+ * due to legal limits?
+ */
+ bool legal_capped;
+
+};
+
+
+/**
+ * Data extracted per coin.
+ */
+struct RefundCoinData
+{
+
+ /**
+ * Public key of a coin.
+ */
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+
+ /**
+ * Amount deposited for this coin.
+ */
+ struct TALER_Amount deposited_with_fee;
+
+ /**
+ * Amount refunded already for this coin.
+ */
+ struct TALER_Amount refund_amount;
+
+ /**
+ * Order serial (actually not really per-coin).
+ */
+ uint64_t order_serial;
+
+ /**
+ * Maximum rtransaction_id for this coin so far.
+ */
+ uint64_t max_rtransaction_id;
+
+ /**
+ * Exchange this coin was issued by.
+ */
+ char *exchange_url;
+
+};
+
+
+/**
+ * Find an exchange record for the refund limit enforcement.
+ *
+ * @param irc refund context
+ * @param exchange_url base URL of the exchange
+ */
+static struct ExchangeLimit *
+find_exchange (struct InsertRefundContext *irc,
+ const char *exchange_url)
+{
+ if (NULL == irc->olc)
+ return NULL; /* no limits */
+ /* Check if entry exists, if so, do nothing */
+ for (struct ExchangeLimit *el = irc->el_head;
+ NULL != el;
+ el = el->next)
+ if (0 == strcmp (exchange_url,
+ el->exchange_url))
+ return el;
+ return NULL;
+}
+
+
+/**
+ * Setup an exchange for the refund limit enforcement and initialize the
+ * original refund limit for the exchange.
+ *
+ * @param irc refund context
+ * @param exchange_url base URL of the exchange
+ * @return limiting data structure
+ */
+static struct ExchangeLimit *
+setup_exchange (struct InsertRefundContext *irc,
+ const char *exchange_url)
+{
+ struct ExchangeLimit *el;
+
+ if (NULL == irc->olc)
+ return NULL; /* no limits */
+ /* Check if entry exists, if so, do nothing */
+ if (NULL !=
+ (el = find_exchange (irc,
+ exchange_url)))
+ return el;
+ el = GNUNET_new (struct ExchangeLimit);
+ el->exchange_url = GNUNET_strdup (exchange_url);
+ /* olc only lowers, so set to the maximum amount we care about */
+ el->remaining_refund_limit = *irc->refund;
+ irc->olc (irc->olc_cls,
+ exchange_url,
+ &el->remaining_refund_limit);
+ GNUNET_CONTAINER_DLL_insert (irc->el_head,
+ irc->el_tail,
+ el);
+ return el;
+}
+
+
+/**
+ * Lower the remaining refund limit in @a el by @a val.
+ *
+ * @param[in,out] el exchange limit to lower
+ * @param val amount to lower limit by
+ * @return true on success, false on failure
+ */
+static bool
+lower_balance (struct ExchangeLimit *el,
+ const struct TALER_Amount *val)
+{
+ if (NULL == el)
+ return true;
+ return 0 <= TALER_amount_subtract (&el->remaining_refund_limit,
+ &el->remaining_refund_limit,
+ val);
+}
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure, our `struct FindRefundContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+process_refund_cb (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct FindRefundContext *ictx = cls;
+
+ for (unsigned int i = 0; i<num_results; i++)
+ {
+ /* Sum up existing refunds */
+ struct TALER_Amount acc;
+ uint64_t rtransaction_id;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount_with_currency ("refund_amount",
+ &acc),
+ GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
+ &rtransaction_id),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ ictx->err = true;
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_amount_cmp_currency (&ictx->refunded_amount,
+ &acc))
+ {
+ GNUNET_break (0);
+ ictx->err = true;
+ return;
+ }
+ if (0 >
+ TALER_amount_add (&ictx->refunded_amount,
+ &ictx->refunded_amount,
+ &acc))
+ {
+ GNUNET_break (0);
+ ictx->err = true;
+ return;
+ }
+ ictx->max_rtransaction_id = GNUNET_MAX (ictx->max_rtransaction_id,
+ rtransaction_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found refund of %s\n",
+ TALER_amount2s (&acc));
+ }
+}
+
+
+/**
+ * Helper function to prepare statement to select refunds
+ *
+ * @param pg context to prepare statement in
+ * @return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS on success
+ */
+static enum GNUNET_DB_QueryStatus
+prep_select_refund (struct TALER_MERCHANTDB_PostgresContext *pg)
+{
+ TMH_PQ_prepare_anon (pg,
+ "SELECT"
+ " refund_amount"
+ ",rtransaction_id"
+ " FROM merchant_refunds"
+ " WHERE coin_pub=$1"
+ " AND order_serial=$2");
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+}
+
+
+/**
+ * Helper function to prepare statement to insert refund
+ *
+ * @param pg context to prepare statement in
+ * @return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS on success
+ */
+static enum GNUNET_DB_QueryStatus
+prep_insert_refund (struct TALER_MERCHANTDB_PostgresContext *pg)
+{
+ // FIXME: return 'refund_serial' from this INSERT statement for #10577
+ TMH_PQ_prepare_anon (pg,
+ "INSERT INTO merchant_refunds"
+ "(order_serial"
+ ",rtransaction_id"
+ ",refund_timestamp"
+ ",coin_pub"
+ ",reason"
+ ",refund_amount"
+ ") VALUES"
+ "($1, $2, $3, $4, $5, $6)");
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+}
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure, our `struct InsertRefundContext`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+process_deposits_for_refund_cb (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct InsertRefundContext *ctx = cls;
+ struct TALER_MERCHANTDB_PostgresContext *pg = ctx->pg;
+ struct TALER_Amount current_refund;
+ struct RefundCoinData rcd[GNUNET_NZL (num_results)];
+ struct GNUNET_TIME_Timestamp now;
+
+ now = GNUNET_TIME_timestamp_get ();
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (ctx->refund->currency,
+ ¤t_refund));
+ memset (rcd,
+ 0,
+ sizeof (rcd));
+ /* Pass 1: Collect amount of existing refunds into current_refund.
+ * Also store existing refunded amount for each deposit in deposit_refund. */
+ for (unsigned int i = 0; i<num_results; i++)
+ {
+ struct RefundCoinData *rcdi = &rcd[i];
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &rcdi->coin_pub),
+ GNUNET_PQ_result_spec_uint64 ("order_serial",
+ &rcdi->order_serial),
+ GNUNET_PQ_result_spec_string ("exchange_url",
+ &rcdi->exchange_url),
+ TALER_PQ_result_spec_amount_with_currency ("amount_with_fee",
+ &rcdi->deposited_with_fee),
+ GNUNET_PQ_result_spec_end
+ };
+ struct FindRefundContext ictx = {
+ .pg = pg,
+ };
+ struct ExchangeLimit *el;
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ el = setup_exchange (ctx,
+ rcdi->exchange_url);
+ if (0 != strcmp (rcdi->deposited_with_fee.currency,
+ ctx->refund->currency))
+ {
+ GNUNET_break_op (0);
+ ctx->rs = TALER_MERCHANTDB_RS_BAD_CURRENCY;
+ goto cleanup;
+ }
+
+ {
+ enum GNUNET_DB_QueryStatus ires;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&rcdi->coin_pub),
+ GNUNET_PQ_query_param_uint64 (&rcdi->order_serial),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_set_zero (
+ ctx->refund->currency,
+ &ictx.refunded_amount));
+ ires = prep_select_refund (pg);
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != ires)
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ ires = GNUNET_PQ_eval_prepared_multi_select (
+ pg->conn,
+ "",
+ params,
+ &process_refund_cb,
+ &ictx);
+ if ( (ictx.err) ||
+ (GNUNET_DB_STATUS_HARD_ERROR == ires) )
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ if (GNUNET_DB_STATUS_SOFT_ERROR == ires)
+ {
+ ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR;
+ goto cleanup;
+ }
+ }
+ if (0 >
+ TALER_amount_add (¤t_refund,
+ ¤t_refund,
+ &ictx.refunded_amount))
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ rcdi->refund_amount = ictx.refunded_amount;
+ rcdi->max_rtransaction_id = ictx.max_rtransaction_id;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Existing refund for coin %s is %s\n",
+ TALER_B2S (&rcdi->coin_pub),
+ TALER_amount2s (&ictx.refunded_amount));
+ GNUNET_break (lower_balance (el,
+ &ictx.refunded_amount));
+ } /* end for all deposited coins */
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Total existing refund is %s\n",
+ TALER_amount2s (¤t_refund));
+
+ /* stop immediately if we are 'done' === amount already
+ * refunded. */
+ if (0 >= TALER_amount_cmp (ctx->refund,
+ ¤t_refund))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Existing refund of %s at or above requested refund. Finished early.\n",
+ TALER_amount2s (¤t_refund));
+ ctx->rs = TALER_MERCHANTDB_RS_SUCCESS;
+ goto cleanup;
+ }
+
+ /* Phase 2: Try to increase current refund until it matches desired refund */
+ for (unsigned int i = 0; i<num_results; i++)
+ {
+ struct RefundCoinData *rcdi = &rcd[i];
+ const struct TALER_Amount *increment;
+ struct TALER_Amount left;
+ struct TALER_Amount remaining_refund;
+ struct ExchangeLimit *el;
+
+ /* How much of the coin is left after the existing refunds? */
+ if (0 >
+ TALER_amount_subtract (&left,
+ &rcdi->deposited_with_fee,
+ &rcdi->refund_amount))
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+
+ if (TALER_amount_is_zero (&left))
+ {
+ /* coin was fully refunded, move to next coin */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Coin %s fully refunded, moving to next coin\n",
+ TALER_B2S (&rcdi->coin_pub));
+ continue;
+ }
+ el = find_exchange (ctx,
+ rcdi->exchange_url);
+ if ( (NULL != el) &&
+ (TALER_amount_is_zero (&el->remaining_refund_limit)) )
+ {
+ /* legal limit reached, move to next coin */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Exchange %s legal limit reached, moving to next coin\n",
+ rcdi->exchange_url);
+ continue;
+ }
+
+ rcdi->max_rtransaction_id++;
+ /* How much of the refund is still to be paid back? */
+ if (0 >
+ TALER_amount_subtract (&remaining_refund,
+ ctx->refund,
+ ¤t_refund))
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ /* cap by legal limit */
+ if (NULL != el)
+ {
+ struct TALER_Amount new_limit;
+
+ TALER_amount_min (&new_limit,
+ &remaining_refund,
+ &el->remaining_refund_limit);
+ if (0 != TALER_amount_cmp (&new_limit,
+ &remaining_refund))
+ {
+ remaining_refund = new_limit;
+ ctx->legal_capped = true;
+ }
+ }
+ /* By how much will we increase the refund for this coin? */
+ if (0 >= TALER_amount_cmp (&remaining_refund,
+ &left))
+ {
+ /* remaining_refund <= left */
+ increment = &remaining_refund;
+ }
+ else
+ {
+ increment = &left;
+ }
+
+ if (0 >
+ TALER_amount_add (¤t_refund,
+ ¤t_refund,
+ increment))
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ GNUNET_break (lower_balance (el,
+ increment));
+ /* actually run the refund */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Coin %s deposit amount is %s\n",
+ TALER_B2S (&rcdi->coin_pub),
+ TALER_amount2s (&rcdi->deposited_with_fee));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Coin %s refund will be incremented by %s\n",
+ TALER_B2S (&rcdi->coin_pub),
+ TALER_amount2s (increment));
+ {
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&rcdi->order_serial),
+ GNUNET_PQ_query_param_uint64 (&rcdi->max_rtransaction_id), /* already inc'ed */
+ GNUNET_PQ_query_param_timestamp (&now),
+ GNUNET_PQ_query_param_auto_from_type (&rcdi->coin_pub),
+ GNUNET_PQ_query_param_string (ctx->reason),
+ TALER_PQ_query_param_amount_with_currency (pg->conn,
+ increment),
+ GNUNET_PQ_query_param_end
+ };
+
+ qs = prep_insert_refund (pg);
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
+ {
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ }
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ params);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
+ goto cleanup;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR;
+ goto cleanup;
+ default:
+ ctx->rs = (enum TALER_MERCHANTDB_RefundStatus) qs;
+ break;
+ }
+ }
+
+ /* stop immediately if we are done */
+ if (0 == TALER_amount_cmp (ctx->refund,
+ ¤t_refund))
+ {
+ ctx->rs = TALER_MERCHANTDB_RS_SUCCESS;
+ goto cleanup;
+ }
+ }
+
+ if (ctx->legal_capped)
+ {
+ ctx->rs = TALER_MERCHANTDB_RS_LEGAL_FAILURE;
+ goto cleanup;
+ }
+ /**
+ * We end up here if not all of the refund has been covered.
+ * Although this should be checked as the business should never
+ * issue a refund bigger than the contract's actual price, we cannot
+ * rely upon the frontend being correct.
+ */
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "The refund of %s is bigger than the order's value\n",
+ TALER_amount2s (ctx->refund));
+ ctx->rs = TALER_MERCHANTDB_RS_TOO_HIGH;
+cleanup:
+ for (unsigned int i = 0; i<num_results; i++)
+ GNUNET_free (rcd[i].exchange_url);
+}
+
+
+enum TALER_MERCHANTDB_RefundStatus
+TALER_MERCHANTDB_do_increase_refund (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ const char *order_id,
+ const struct TALER_Amount *refund,
+ TALER_MERCHANTDB_OperationLimitCallback olc,
+ void *olc_cls,
+ const char *reason)
+{
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (order_id),
+ GNUNET_PQ_query_param_end
+ };
+ struct InsertRefundContext ctx = {
+ .pg = pg,
+ .refund = refund,
+ .olc = olc,
+ .olc_cls = olc_cls,
+ .reason = reason,
+ };
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (instance_id,
+ pg->current_merchant_id));
+ TMH_PQ_prepare_anon (pg,
+ "SELECT"
+ " dep.coin_pub"
+ ",dco.order_serial"
+ ",dep.amount_with_fee"
+ ",dco.exchange_url"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations dco"
+ " USING (deposit_confirmation_serial)"
+ " WHERE order_serial="
+ " (SELECT order_serial"
+ " FROM merchant_contract_terms"
+ " WHERE order_id=$1"
+ " AND paid)");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Asked to refund %s on order %s\n",
+ TALER_amount2s (refund),
+ order_id);
+ qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+ "",
+ params,
+ &process_deposits_for_refund_cb,
+ &ctx);
+ {
+ struct ExchangeLimit *el;
+
+ while (NULL != (el = ctx.el_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (ctx.el_head,
+ ctx.el_tail,
+ el);
+ GNUNET_free (el->exchange_url);
+ GNUNET_free (el);
+ }
+ }
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ /* never paid, means we clearly cannot refund anything */
+ return TALER_MERCHANTDB_RS_NO_SUCH_ORDER;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ return TALER_MERCHANTDB_RS_SOFT_ERROR;
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ return TALER_MERCHANTDB_RS_HARD_ERROR;
+ default:
+ /* Got one or more deposits */
+ return ctx.rs;
+ }
+}
diff --git a/src/backenddb/do_insert_account.c b/src/backenddb/do_insert_account.c
@@ -0,0 +1,80 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/do_insert_account.c
+ * @brief Implementation of the do_insert_account function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/do_insert_account.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_do_insert_account (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const struct TALER_MERCHANTDB_AccountDetails *account_details,
+ struct TALER_MerchantWireHashP *h_wire,
+ struct TALER_WireSaltP *salt,
+ bool *not_found,
+ bool *conflict)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&account_details->h_wire),
+ GNUNET_PQ_query_param_auto_from_type (&account_details->salt),
+ GNUNET_PQ_query_param_string (account_details->payto_uri.full_payto),
+ NULL ==account_details->credit_facade_url
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (account_details->credit_facade_url),
+ NULL == account_details->credit_facade_credentials
+ ? GNUNET_PQ_query_param_null ()
+ : TALER_PQ_query_param_json (account_details->credit_facade_credentials),
+ NULL == account_details->extra_wire_subject_metadata
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (
+ account_details->extra_wire_subject_metadata),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("not_found",
+ not_found),
+ GNUNET_PQ_result_spec_bool ("conflict",
+ conflict),
+ GNUNET_PQ_result_spec_auto_from_type ("h_wire",
+ h_wire),
+ GNUNET_PQ_result_spec_auto_from_type ("salt",
+ salt),
+ GNUNET_PQ_result_spec_end
+ };
+
+ GNUNET_assert (account_details->active);
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (account_details->instance_id,
+ pg->current_merchant_id));
+ TMH_PQ_prepare_anon (pg,
+ "SELECT "
+ " out_h_wire AS h_wire"
+ " ,out_salt AS salt"
+ " ,out_conflict AS conflict"
+ " ,out_not_found AS not_found"
+ " FROM merchant_do_activate_account"
+ " ($1,$2,$3,$4,$5,$6);");
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "",
+ params,
+ rs);
+}
diff --git a/src/backenddb/activate_account.sql b/src/backenddb/do_insert_account.sql
diff --git a/src/backenddb/do_solve_mfa_challenge.c b/src/backenddb/do_solve_mfa_challenge.c
@@ -0,0 +1,80 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/do_solve_mfa_challenge.c
+ * @brief Implementation of the do_solve_mfa_challenge function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "taler/taler_merchant_util.h"
+#include "merchant-database/do_solve_mfa_challenge.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_do_solve_mfa_challenge (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ uint64_t challenge_id,
+ const struct TALER_MERCHANT_MFA_BodyHash *h_body,
+ const char *solution,
+ bool *solved,
+ uint32_t *retry_counter)
+{
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ bool no_match;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&challenge_id),
+ GNUNET_PQ_query_param_auto_from_type (h_body),
+ GNUNET_PQ_query_param_string (solution),
+ GNUNET_PQ_query_param_absolute_time (&now),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("out_solved",
+ solved),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_uint32 ("out_retry_counter",
+ retry_counter),
+ &no_match),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ /* conservatively set security-relevant return values to
+ safe values, even though these should not be used with qs <= 0 */
+ *solved = false;
+ *retry_counter = 0;
+ TMH_PQ_prepare_anon (pg,
+ "SELECT"
+ " out_solved"
+ " ,out_retry_counter"
+ " FROM merchant.merchant_do_solve_mfa_challenge"
+ " ($1, $2, $3, $4);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "",
+ params,
+ rs);
+ if (qs <= 0)
+ return qs;
+ if (no_match)
+ {
+ GNUNET_PQ_cleanup_result (rs);
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ }
+ GNUNET_PQ_cleanup_result (rs);
+ return qs;
+}
diff --git a/src/backenddb/solve_mfa_challenge.sql b/src/backenddb/do_solve_mfa_challenge.sql
diff --git a/src/backenddb/expire_locks.c b/src/backenddb/expire_locks.c
@@ -1,60 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/expire_locks.c
- * @brief Implementation of the expire_locks function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/expire_locks.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_expire_locks (struct TALER_MERCHANTDB_PostgresContext *pg)
-{
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- uint64_t total;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("expire_locks",
- &total),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- PREPARE (pg,
- "expire_locks",
- "SELECT expire_locks($1) "
- " AS expire_locks");
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "expire_locks",
- params,
- rs);
- if (qs < 0)
- {
- GNUNET_break (0);
- return qs;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Released %llu locks for the current instance\n",
- (unsigned long long) total);
- return (enum GNUNET_DB_QueryStatus) total;
-}
diff --git a/src/backenddb/finalize_transfer_status.c b/src/backenddb/finalize_transfer_status.c
@@ -1,76 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/finalize_transfer_status.c
- * @brief Implementation of the finalize_transfer_status function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/finalize_transfer_status.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_finalize_transfer_status (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *exchange_url,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct GNUNET_HashCode *h_details,
- const struct TALER_Amount *total_amount,
- const struct TALER_Amount *wire_fee,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_ExchangeSignatureP *exchange_sig)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_string (exchange_url),
- TALER_PQ_query_param_amount_with_currency (pg->conn,
- total_amount),
- TALER_PQ_query_param_amount_with_currency (pg->conn,
- wire_fee),
- GNUNET_PQ_query_param_auto_from_type (h_details),
- GNUNET_PQ_query_param_auto_from_type (exchange_pub),
- GNUNET_PQ_query_param_auto_from_type (exchange_sig),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- TMH_PQ_prepare_anon (pg,
- "WITH subquery AS ("
- " SELECT signkey_serial"
- " FROM merchant.merchant_exchange_signing_keys"
- " WHERE exchange_pub=$6"
- ")"
- "UPDATE merchant_expected_transfers SET"
- " last_http_status=200"
- ",last_ec=0"
- ",last_detail=NULL"
- ",retry_needed=FALSE"
- ",retry_time=0"
- ",expected_credit_amount=$3"
- ",wire_fee=$4"
- ",h_details=$5"
- ",signkey_serial=subquery.signkey_serial"
- ",exchange_sig=$7"
- " FROM subquery"
- " WHERE wtid=$1"
- " AND exchange_url=$2");
- return GNUNET_PQ_eval_prepared_non_select (
- pg->conn,
- "",
- params);
-}
diff --git a/src/backenddb/inactivate_account.c b/src/backenddb/inactivate_account.c
@@ -1,61 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/inactivate_account.c
- * @brief Implementation of the inactivate_account function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/inactivate_account.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_inactivate_account (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *merchant_id,
- const struct TALER_MerchantWireHashP *h_wire)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_wire),
- GNUNET_PQ_query_param_end
- };
- bool found;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("found",
- &found),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (merchant_id,
- pg->current_merchant_id));
- TMH_PQ_prepare_anon (pg,
- "SELECT out_found AS found"
- " FROM merchant_do_inactivate_account"
- " ($1);");
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "",
- params,
- rs);
- if (qs < 0)
- return qs;
- if (! found)
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- return qs;
-}
diff --git a/src/backenddb/increase_refund.c b/src/backenddb/increase_refund.c
@@ -1,740 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022-2024 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/increase_refund.c
- * @brief Implementation of the increase_refund function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/increase_refund.h"
-#include "helper.h"
-
-
-/**
- * Information about refund limits per exchange.
- */
-struct ExchangeLimit
-{
- /**
- * Kept in a DLL.
- */
- struct ExchangeLimit *next;
-
- /**
- * Kept in a DLL.
- */
- struct ExchangeLimit *prev;
-
- /**
- * Exchange the limit is about.
- */
- char *exchange_url;
-
- /**
- * Refund amount remaining at this exchange.
- */
- struct TALER_Amount remaining_refund_limit;
-
-};
-
-
-/**
- * Closure for #process_refund_cb().
- */
-struct FindRefundContext
-{
-
- /**
- * Plugin context.
- */
- struct TALER_MERCHANTDB_PostgresContext *pg;
-
- /**
- * Updated to reflect total amount refunded so far.
- */
- struct TALER_Amount refunded_amount;
-
- /**
- * Set to the largest refund transaction ID encountered.
- */
- uint64_t max_rtransaction_id;
-
- /**
- * Set to true on hard errors.
- */
- bool err;
-};
-
-
-/**
- * Closure for #process_deposits_for_refund_cb().
- */
-struct InsertRefundContext
-{
- /**
- * Used to provide a connection to the db
- */
- struct TALER_MERCHANTDB_PostgresContext *pg;
-
- /**
- * Head of DLL of per-exchange refund limits.
- */
- struct ExchangeLimit *el_head;
-
- /**
- * Tail of DLL of per-exchange refund limits.
- */
- struct ExchangeLimit *el_tail;
-
- /**
- * Amount to which increase the refund for this contract
- */
- const struct TALER_Amount *refund;
-
- /**
- * Human-readable reason behind this refund
- */
- const char *reason;
-
- /**
- * Function to call to determine per-exchange limits.
- * NULL for no limits.
- */
- TALER_MERCHANTDB_OperationLimitCallback olc;
-
- /**
- * Closure for @e olc.
- */
- void *olc_cls;
-
- /**
- * Transaction status code.
- */
- enum TALER_MERCHANTDB_RefundStatus rs;
-
- /**
- * Did we have to cap refunds of any coin
- * due to legal limits?
- */
- bool legal_capped;
-
-};
-
-
-/**
- * Data extracted per coin.
- */
-struct RefundCoinData
-{
-
- /**
- * Public key of a coin.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Amount deposited for this coin.
- */
- struct TALER_Amount deposited_with_fee;
-
- /**
- * Amount refunded already for this coin.
- */
- struct TALER_Amount refund_amount;
-
- /**
- * Order serial (actually not really per-coin).
- */
- uint64_t order_serial;
-
- /**
- * Maximum rtransaction_id for this coin so far.
- */
- uint64_t max_rtransaction_id;
-
- /**
- * Exchange this coin was issued by.
- */
- char *exchange_url;
-
-};
-
-
-/**
- * Find an exchange record for the refund limit enforcement.
- *
- * @param irc refund context
- * @param exchange_url base URL of the exchange
- */
-static struct ExchangeLimit *
-find_exchange (struct InsertRefundContext *irc,
- const char *exchange_url)
-{
- if (NULL == irc->olc)
- return NULL; /* no limits */
- /* Check if entry exists, if so, do nothing */
- for (struct ExchangeLimit *el = irc->el_head;
- NULL != el;
- el = el->next)
- if (0 == strcmp (exchange_url,
- el->exchange_url))
- return el;
- return NULL;
-}
-
-
-/**
- * Setup an exchange for the refund limit enforcement and initialize the
- * original refund limit for the exchange.
- *
- * @param irc refund context
- * @param exchange_url base URL of the exchange
- * @return limiting data structure
- */
-static struct ExchangeLimit *
-setup_exchange (struct InsertRefundContext *irc,
- const char *exchange_url)
-{
- struct ExchangeLimit *el;
-
- if (NULL == irc->olc)
- return NULL; /* no limits */
- /* Check if entry exists, if so, do nothing */
- if (NULL !=
- (el = find_exchange (irc,
- exchange_url)))
- return el;
- el = GNUNET_new (struct ExchangeLimit);
- el->exchange_url = GNUNET_strdup (exchange_url);
- /* olc only lowers, so set to the maximum amount we care about */
- el->remaining_refund_limit = *irc->refund;
- irc->olc (irc->olc_cls,
- exchange_url,
- &el->remaining_refund_limit);
- GNUNET_CONTAINER_DLL_insert (irc->el_head,
- irc->el_tail,
- el);
- return el;
-}
-
-
-/**
- * Lower the remaining refund limit in @a el by @a val.
- *
- * @param[in,out] el exchange limit to lower
- * @param val amount to lower limit by
- * @return true on success, false on failure
- */
-static bool
-lower_balance (struct ExchangeLimit *el,
- const struct TALER_Amount *val)
-{
- if (NULL == el)
- return true;
- return 0 <= TALER_amount_subtract (&el->remaining_refund_limit,
- &el->remaining_refund_limit,
- val);
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure, our `struct FindRefundContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-process_refund_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct FindRefundContext *ictx = cls;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- /* Sum up existing refunds */
- struct TALER_Amount acc;
- uint64_t rtransaction_id;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_result_spec_amount_with_currency ("refund_amount",
- &acc),
- GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
- &rtransaction_id),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- ictx->err = true;
- return;
- }
- if (GNUNET_OK !=
- TALER_amount_cmp_currency (&ictx->refunded_amount,
- &acc))
- {
- GNUNET_break (0);
- ictx->err = true;
- return;
- }
- if (0 >
- TALER_amount_add (&ictx->refunded_amount,
- &ictx->refunded_amount,
- &acc))
- {
- GNUNET_break (0);
- ictx->err = true;
- return;
- }
- ictx->max_rtransaction_id = GNUNET_MAX (ictx->max_rtransaction_id,
- rtransaction_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Found refund of %s\n",
- TALER_amount2s (&acc));
- }
-}
-
-
-/**
- * Helper function to prepare statement to select refunds
- *
- * @param pg context to prepare statement in
- * @return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS on success
- */
-static enum GNUNET_DB_QueryStatus
-prep_select_refund (struct TALER_MERCHANTDB_PostgresContext *pg)
-{
- TMH_PQ_prepare_anon (pg,
- "SELECT"
- " refund_amount"
- ",rtransaction_id"
- " FROM merchant_refunds"
- " WHERE coin_pub=$1"
- " AND order_serial=$2");
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
-}
-
-
-/**
- * Helper function to prepare statement to insert refund
- *
- * @param pg context to prepare statement in
- * @return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS on success
- */
-static enum GNUNET_DB_QueryStatus
-prep_insert_refund (struct TALER_MERCHANTDB_PostgresContext *pg)
-{
- // FIXME: return 'refund_serial' from this INSERT statement for #10577
- TMH_PQ_prepare_anon (pg,
- "INSERT INTO merchant_refunds"
- "(order_serial"
- ",rtransaction_id"
- ",refund_timestamp"
- ",coin_pub"
- ",reason"
- ",refund_amount"
- ") VALUES"
- "($1, $2, $3, $4, $5, $6)");
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure, our `struct InsertRefundContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-process_deposits_for_refund_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct InsertRefundContext *ctx = cls;
- struct TALER_MERCHANTDB_PostgresContext *pg = ctx->pg;
- struct TALER_Amount current_refund;
- struct RefundCoinData rcd[GNUNET_NZL (num_results)];
- struct GNUNET_TIME_Timestamp now;
-
- now = GNUNET_TIME_timestamp_get ();
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (ctx->refund->currency,
- ¤t_refund));
- memset (rcd,
- 0,
- sizeof (rcd));
- /* Pass 1: Collect amount of existing refunds into current_refund.
- * Also store existing refunded amount for each deposit in deposit_refund. */
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct RefundCoinData *rcdi = &rcd[i];
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &rcdi->coin_pub),
- GNUNET_PQ_result_spec_uint64 ("order_serial",
- &rcdi->order_serial),
- GNUNET_PQ_result_spec_string ("exchange_url",
- &rcdi->exchange_url),
- TALER_PQ_result_spec_amount_with_currency ("amount_with_fee",
- &rcdi->deposited_with_fee),
- GNUNET_PQ_result_spec_end
- };
- struct FindRefundContext ictx = {
- .pg = pg,
- };
- struct ExchangeLimit *el;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- el = setup_exchange (ctx,
- rcdi->exchange_url);
- if (0 != strcmp (rcdi->deposited_with_fee.currency,
- ctx->refund->currency))
- {
- GNUNET_break_op (0);
- ctx->rs = TALER_MERCHANTDB_RS_BAD_CURRENCY;
- goto cleanup;
- }
-
- {
- enum GNUNET_DB_QueryStatus ires;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&rcdi->coin_pub),
- GNUNET_PQ_query_param_uint64 (&rcdi->order_serial),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (
- ctx->refund->currency,
- &ictx.refunded_amount));
- ires = prep_select_refund (pg);
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != ires)
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- ires = GNUNET_PQ_eval_prepared_multi_select (
- pg->conn,
- "",
- params,
- &process_refund_cb,
- &ictx);
- if ( (ictx.err) ||
- (GNUNET_DB_STATUS_HARD_ERROR == ires) )
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- if (GNUNET_DB_STATUS_SOFT_ERROR == ires)
- {
- ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR;
- goto cleanup;
- }
- }
- if (0 >
- TALER_amount_add (¤t_refund,
- ¤t_refund,
- &ictx.refunded_amount))
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- rcdi->refund_amount = ictx.refunded_amount;
- rcdi->max_rtransaction_id = ictx.max_rtransaction_id;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Existing refund for coin %s is %s\n",
- TALER_B2S (&rcdi->coin_pub),
- TALER_amount2s (&ictx.refunded_amount));
- GNUNET_break (lower_balance (el,
- &ictx.refunded_amount));
- } /* end for all deposited coins */
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Total existing refund is %s\n",
- TALER_amount2s (¤t_refund));
-
- /* stop immediately if we are 'done' === amount already
- * refunded. */
- if (0 >= TALER_amount_cmp (ctx->refund,
- ¤t_refund))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Existing refund of %s at or above requested refund. Finished early.\n",
- TALER_amount2s (¤t_refund));
- ctx->rs = TALER_MERCHANTDB_RS_SUCCESS;
- goto cleanup;
- }
-
- /* Phase 2: Try to increase current refund until it matches desired refund */
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct RefundCoinData *rcdi = &rcd[i];
- const struct TALER_Amount *increment;
- struct TALER_Amount left;
- struct TALER_Amount remaining_refund;
- struct ExchangeLimit *el;
-
- /* How much of the coin is left after the existing refunds? */
- if (0 >
- TALER_amount_subtract (&left,
- &rcdi->deposited_with_fee,
- &rcdi->refund_amount))
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
-
- if (TALER_amount_is_zero (&left))
- {
- /* coin was fully refunded, move to next coin */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Coin %s fully refunded, moving to next coin\n",
- TALER_B2S (&rcdi->coin_pub));
- continue;
- }
- el = find_exchange (ctx,
- rcdi->exchange_url);
- if ( (NULL != el) &&
- (TALER_amount_is_zero (&el->remaining_refund_limit)) )
- {
- /* legal limit reached, move to next coin */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Exchange %s legal limit reached, moving to next coin\n",
- rcdi->exchange_url);
- continue;
- }
-
- rcdi->max_rtransaction_id++;
- /* How much of the refund is still to be paid back? */
- if (0 >
- TALER_amount_subtract (&remaining_refund,
- ctx->refund,
- ¤t_refund))
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- /* cap by legal limit */
- if (NULL != el)
- {
- struct TALER_Amount new_limit;
-
- TALER_amount_min (&new_limit,
- &remaining_refund,
- &el->remaining_refund_limit);
- if (0 != TALER_amount_cmp (&new_limit,
- &remaining_refund))
- {
- remaining_refund = new_limit;
- ctx->legal_capped = true;
- }
- }
- /* By how much will we increase the refund for this coin? */
- if (0 >= TALER_amount_cmp (&remaining_refund,
- &left))
- {
- /* remaining_refund <= left */
- increment = &remaining_refund;
- }
- else
- {
- increment = &left;
- }
-
- if (0 >
- TALER_amount_add (¤t_refund,
- ¤t_refund,
- increment))
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- GNUNET_break (lower_balance (el,
- increment));
- /* actually run the refund */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Coin %s deposit amount is %s\n",
- TALER_B2S (&rcdi->coin_pub),
- TALER_amount2s (&rcdi->deposited_with_fee));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Coin %s refund will be incremented by %s\n",
- TALER_B2S (&rcdi->coin_pub),
- TALER_amount2s (increment));
- {
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&rcdi->order_serial),
- GNUNET_PQ_query_param_uint64 (&rcdi->max_rtransaction_id), /* already inc'ed */
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_auto_from_type (&rcdi->coin_pub),
- GNUNET_PQ_query_param_string (ctx->reason),
- TALER_PQ_query_param_amount_with_currency (pg->conn,
- increment),
- GNUNET_PQ_query_param_end
- };
-
- qs = prep_insert_refund (pg);
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
- {
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- }
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- params);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR;
- goto cleanup;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR;
- goto cleanup;
- default:
- ctx->rs = (enum TALER_MERCHANTDB_RefundStatus) qs;
- break;
- }
- }
-
- /* stop immediately if we are done */
- if (0 == TALER_amount_cmp (ctx->refund,
- ¤t_refund))
- {
- ctx->rs = TALER_MERCHANTDB_RS_SUCCESS;
- goto cleanup;
- }
- }
-
- if (ctx->legal_capped)
- {
- ctx->rs = TALER_MERCHANTDB_RS_LEGAL_FAILURE;
- goto cleanup;
- }
- /**
- * We end up here if not all of the refund has been covered.
- * Although this should be checked as the business should never
- * issue a refund bigger than the contract's actual price, we cannot
- * rely upon the frontend being correct.
- */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "The refund of %s is bigger than the order's value\n",
- TALER_amount2s (ctx->refund));
- ctx->rs = TALER_MERCHANTDB_RS_TOO_HIGH;
-cleanup:
- for (unsigned int i = 0; i<num_results; i++)
- GNUNET_free (rcd[i].exchange_url);
-}
-
-
-enum TALER_MERCHANTDB_RefundStatus
-TALER_MERCHANTDB_increase_refund (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- const char *order_id,
- const struct TALER_Amount *refund,
- TALER_MERCHANTDB_OperationLimitCallback olc,
- void *olc_cls,
- const char *reason)
-{
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (order_id),
- GNUNET_PQ_query_param_end
- };
- struct InsertRefundContext ctx = {
- .pg = pg,
- .refund = refund,
- .olc = olc,
- .olc_cls = olc_cls,
- .reason = reason,
- };
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (instance_id,
- pg->current_merchant_id));
- TMH_PQ_prepare_anon (pg,
- "SELECT"
- " dep.coin_pub"
- ",dco.order_serial"
- ",dep.amount_with_fee"
- ",dco.exchange_url"
- " FROM merchant_deposits dep"
- " JOIN merchant_deposit_confirmations dco"
- " USING (deposit_confirmation_serial)"
- " WHERE order_serial="
- " (SELECT order_serial"
- " FROM merchant_contract_terms"
- " WHERE order_id=$1"
- " AND paid)");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Asked to refund %s on order %s\n",
- TALER_amount2s (refund),
- order_id);
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "",
- params,
- &process_deposits_for_refund_cb,
- &ctx);
- {
- struct ExchangeLimit *el;
-
- while (NULL != (el = ctx.el_head))
- {
- GNUNET_CONTAINER_DLL_remove (ctx.el_head,
- ctx.el_tail,
- el);
- GNUNET_free (el->exchange_url);
- GNUNET_free (el);
- }
- }
- switch (qs)
- {
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* never paid, means we clearly cannot refund anything */
- return TALER_MERCHANTDB_RS_NO_SUCH_ORDER;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return TALER_MERCHANTDB_RS_SOFT_ERROR;
- case GNUNET_DB_STATUS_HARD_ERROR:
- return TALER_MERCHANTDB_RS_HARD_ERROR;
- default:
- /* Got one or more deposits */
- return ctx.rs;
- }
-}
diff --git a/src/backenddb/increment_money_pots.c b/src/backenddb/increment_money_pots.c
@@ -1,76 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/increment_money_pots.c
- * @brief Implementation of the increment_money_pots function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_error_codes.h>
-#include <taler/taler_dbevents.h>
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/increment_money_pots.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_increment_money_pots (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- size_t money_pots_len,
- const uint64_t *money_pot_ids,
- const struct TALER_Amount *pot_increments)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_array_uint64 (money_pots_len,
- money_pot_ids,
- pg->conn),
- TALER_PQ_query_param_array_amount_with_currency (money_pots_len,
- pot_increments,
- "merchant",
- pg->conn),
- GNUNET_PQ_query_param_end
- };
- bool not_found;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("not_found",
- ¬_found),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (instance_id,
- pg->current_merchant_id));
- TMH_PQ_prepare_anon (pg,
- "SELECT"
- " out_not_found AS not_found"
- " FROM merchant_do_increment_money_pots"
- "($1,$2);");
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "",
- params,
- rs);
- GNUNET_PQ_cleanup_query_params_closures (params);
- if (qs <= 0)
- return qs;
- if (not_found)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Some money pots could not be implemented because they no longer exist. This is not a bug and expected to happen if a merchant deletes money pots that were used in orders active at the time.\n");
- }
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-}
diff --git a/src/backenddb/insert_donau_keys.c b/src/backenddb/insert_donau_keys.c
@@ -0,0 +1,70 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/insert_donau_keys.c
+ * @brief Implementation of the insert_donau_keys function for Postgres
+ * @author Bohdan Potuzhnyi
+ * @author Vlada Svirsh
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "donau/donau_service.h"
+#include "merchant-database/insert_donau_keys.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_donau_keys (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const struct DONAU_Keys *keys,
+ struct GNUNET_TIME_Absolute first_retry)
+{
+ enum GNUNET_DB_QueryStatus qs;
+ json_t *jkeys = DONAU_keys_to_json (keys);
+
+ if (NULL == jkeys)
+ return GNUNET_DB_STATUS_HARD_ERROR;
+
+ {
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_json (jkeys),
+ GNUNET_PQ_query_param_absolute_time (&first_retry),
+ GNUNET_PQ_query_param_string (keys->donau_url),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "insert_donau_keys",
+ "INSERT INTO merchant.merchant_donau_keys"
+ " (keys_json"
+ " ,first_retry"
+ " ,donau_url"
+ " ) VALUES ("
+ " $1::TEXT::JSONB"
+ " ,$2"
+ " ,$3)"
+ " ON CONFLICT (donau_url)"
+ " DO UPDATE SET"
+ " keys_json=EXCLUDED.keys_json,"
+ " first_retry=EXCLUDED.first_retry;");
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_donau_keys",
+ params);
+ }
+
+ json_decref (jkeys);
+ return qs;
+}
diff --git a/src/backenddb/insert_inventory_lock.c b/src/backenddb/insert_inventory_lock.c
@@ -0,0 +1,93 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/insert_inventory_lock.c
+ * @brief Implementation of the insert_inventory_lock function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/insert_inventory_lock.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_inventory_lock (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ const char *product_id,
+ const struct GNUNET_Uuid *uuid,
+ uint64_t quantity,
+ uint32_t quantity_frac,
+ struct GNUNET_TIME_Timestamp expiration_time)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (product_id),
+ GNUNET_PQ_query_param_auto_from_type (uuid),
+ GNUNET_PQ_query_param_uint64 (&quantity),
+ GNUNET_PQ_query_param_uint32 (&quantity_frac),
+ GNUNET_PQ_query_param_timestamp (&expiration_time),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (instance_id,
+ pg->current_merchant_id));
+ TMH_PQ_prepare_anon (pg,
+ "WITH tmp AS"
+ " (SELECT"
+ " mi.product_serial"
+ " ,mi.total_stock"
+ " ,mi.total_stock_frac"
+ " ,mi.total_sold"
+ " ,mi.total_sold_frac"
+ " ,mi.total_lost"
+ " ,mi.total_lost_frac"
+ " ,mi.allow_fractional_quantity"
+ " FROM merchant_inventory mi"
+ " WHERE mi.product_id=$1)"
+ "INSERT INTO merchant_inventory_locks"
+ "(product_serial"
+ ",lock_uuid"
+ ",total_locked"
+ ",total_locked_frac"
+ ",expiration)"
+ " SELECT tmp.product_serial, $2, $3::INT8, $4::INT4, $5"
+ " FROM tmp"
+ " WHERE (tmp.allow_fractional_quantity OR $4 = 0)"
+ " AND (tmp.total_stock = 9223372036854775807"
+ " OR ("
+ " (tmp.total_stock::NUMERIC * 1000000"
+ " + tmp.total_stock_frac::NUMERIC)"
+ " - (tmp.total_sold::NUMERIC * 1000000"
+ " + tmp.total_sold_frac::NUMERIC)"
+ " - (tmp.total_lost::NUMERIC * 1000000"
+ " + tmp.total_lost_frac::NUMERIC)"
+ " >= "
+ " (($3::NUMERIC * 1000000) + $4::NUMERIC)"
+ " + (SELECT COALESCE(SUM(total_locked::NUMERIC * 1000000"
+ " + total_locked_frac::NUMERIC), 0)"
+ " FROM merchant_inventory_locks mil"
+ " WHERE mil.product_serial = tmp.product_serial)"
+ " + (SELECT COALESCE(SUM(total_locked::NUMERIC * 1000000"
+ " + total_locked_frac::NUMERIC), 0)"
+ " FROM merchant_order_locks mol"
+ " WHERE mol.product_serial = tmp.product_serial)"
+ " ))");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ params);
+}
diff --git a/src/backenddb/insert_mfa_challenge.c b/src/backenddb/insert_mfa_challenge.c
@@ -0,0 +1,86 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/insert_mfa_challenge.c
+ * @brief Implementation of the insert_mfa_challenge function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "taler/taler_merchant_util.h"
+#include "merchantdb_lib.h"
+#include "merchant-database/insert_mfa_challenge.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_mfa_challenge (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_name,
+ enum TALER_MERCHANT_MFA_CriticalOperation op,
+ const struct TALER_MERCHANT_MFA_BodyHash *h_body,
+ const struct TALER_MERCHANT_MFA_BodySalt *salt,
+ const char *code,
+ struct GNUNET_TIME_Absolute expiration_date,
+ struct GNUNET_TIME_Absolute retransmission_date,
+ enum TALER_MERCHANT_MFA_Channel tan_channel,
+ const char *required_address,
+ uint64_t *challenge_id)
+{
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ const char *op_str = TALER_MERCHANT_MFA_co_to_string (op);
+ const char *channel_str = TALER_MERCHANT_MFA_channel_to_string (tan_channel);
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_body),
+ GNUNET_PQ_query_param_auto_from_type (salt),
+ GNUNET_PQ_query_param_string (op_str),
+ GNUNET_PQ_query_param_string (code),
+ GNUNET_PQ_query_param_absolute_time (&now), /* $5 */
+ GNUNET_PQ_query_param_absolute_time (&expiration_date),
+ GNUNET_PQ_query_param_absolute_time (&retransmission_date),
+ GNUNET_PQ_query_param_string (channel_str),
+ GNUNET_PQ_query_param_string (required_address), /* $9 */
+ GNUNET_PQ_query_param_string (instance_name),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("challenge_id",
+ challenge_id),
+ GNUNET_PQ_result_spec_end
+ };
+
+ PREPARE (pg,
+ "create_mfa_challenge",
+ "INSERT INTO merchant.tan_challenges"
+ " (h_body"
+ " ,salt"
+ " ,op"
+ " ,code"
+ " ,creation_date"
+ " ,expiration_date"
+ " ,retransmission_date"
+ " ,retry_counter" /* always set to 3 */
+ " ,tan_channel"
+ " ,required_address"
+ " ,instance_name)"
+ " VALUES"
+ " ($1, $2, $3, $4, $5, $6, $7, 3, $8, $9, $10)"
+ " RETURNING challenge_id;");
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "create_mfa_challenge",
+ params,
+ rs);
+}
diff --git a/src/backenddb/insert_refund_by_coin.c b/src/backenddb/insert_refund_by_coin.c
@@ -0,0 +1,74 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/insert_refund_by_coin.c
+ * @brief Implementation of the insert_refund_by_coin function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/insert_refund_by_coin.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_refund_by_coin (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ 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)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+ GNUNET_PQ_query_param_timestamp (&refund_timestamp),
+ GNUNET_PQ_query_param_auto_from_type (coin_pub),
+ GNUNET_PQ_query_param_string (reason),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (instance_id,
+ pg->current_merchant_id));
+ TMH_PQ_prepare_anon (pg,
+ "INSERT INTO merchant_refunds"
+ "(order_serial"
+ ",rtransaction_id"
+ ",refund_timestamp"
+ ",coin_pub"
+ ",reason"
+ ",refund_amount"
+ ") "
+ "SELECT "
+ " dcon.order_serial"
+ ",0" /* rtransaction_id always 0 for /abort */
+ ",$2"
+ ",dep.coin_pub"
+ ",$4"
+ ",dep.amount_with_fee"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations dcon"
+ " USING (deposit_confirmation_serial)"
+ " WHERE dep.coin_pub=$3"
+ " AND dcon.order_serial="
+ " (SELECT order_serial"
+ " FROM merchant_contract_terms"
+ " WHERE h_contract_terms=$1)");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ params);
+}
diff --git a/src/backenddb/insert_wire_fee.c b/src/backenddb/insert_wire_fee.c
@@ -0,0 +1,72 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/insert_wire_fee.c
+ * @brief Implementation of the insert_wire_fee function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/insert_wire_fee.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_wire_fee (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ 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)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+ GNUNET_PQ_query_param_auto_from_type (h_wire_method),
+ TALER_PQ_query_param_amount_with_currency (pg->conn,
+ &fees->wire),
+ TALER_PQ_query_param_amount_with_currency (pg->conn,
+ &fees->closing),
+ GNUNET_PQ_query_param_timestamp (&start_date),
+ GNUNET_PQ_query_param_timestamp (&end_date),
+ GNUNET_PQ_query_param_auto_from_type (master_sig),
+ GNUNET_PQ_query_param_end
+ };
+
+ /* no preflight check here, run in its own transaction by the caller */
+ PREPARE (pg,
+ "insert_wire_fee",
+ "INSERT INTO merchant.merchant_exchange_wire_fees"
+ "(master_pub"
+ ",h_wire_method"
+ ",wire_fee"
+ ",closing_fee"
+ ",start_date"
+ ",end_date"
+ ",master_sig)"
+ " VALUES "
+ "($1, $2, $3, $4, $5, $6, $7)"
+ " ON CONFLICT DO NOTHING");
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Storing wire fee for %s starting at %s of %s\n",
+ TALER_B2S (master_pub),
+ GNUNET_TIME_timestamp2s (start_date),
+ TALER_amount2s (&fees->wire));
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_wire_fee",
+ params);
+}
diff --git a/src/backenddb/lock_product.c b/src/backenddb/lock_product.c
@@ -1,93 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/lock_product.c
- * @brief Implementation of the lock_product function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/lock_product.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_lock_product (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- const char *product_id,
- const struct GNUNET_Uuid *uuid,
- uint64_t quantity,
- uint32_t quantity_frac,
- struct GNUNET_TIME_Timestamp expiration_time)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (product_id),
- GNUNET_PQ_query_param_auto_from_type (uuid),
- GNUNET_PQ_query_param_uint64 (&quantity),
- GNUNET_PQ_query_param_uint32 (&quantity_frac),
- GNUNET_PQ_query_param_timestamp (&expiration_time),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (instance_id,
- pg->current_merchant_id));
- TMH_PQ_prepare_anon (pg,
- "WITH tmp AS"
- " (SELECT"
- " mi.product_serial"
- " ,mi.total_stock"
- " ,mi.total_stock_frac"
- " ,mi.total_sold"
- " ,mi.total_sold_frac"
- " ,mi.total_lost"
- " ,mi.total_lost_frac"
- " ,mi.allow_fractional_quantity"
- " FROM merchant_inventory mi"
- " WHERE mi.product_id=$1)"
- "INSERT INTO merchant_inventory_locks"
- "(product_serial"
- ",lock_uuid"
- ",total_locked"
- ",total_locked_frac"
- ",expiration)"
- " SELECT tmp.product_serial, $2, $3::INT8, $4::INT4, $5"
- " FROM tmp"
- " WHERE (tmp.allow_fractional_quantity OR $4 = 0)"
- " AND (tmp.total_stock = 9223372036854775807"
- " OR ("
- " (tmp.total_stock::NUMERIC * 1000000"
- " + tmp.total_stock_frac::NUMERIC)"
- " - (tmp.total_sold::NUMERIC * 1000000"
- " + tmp.total_sold_frac::NUMERIC)"
- " - (tmp.total_lost::NUMERIC * 1000000"
- " + tmp.total_lost_frac::NUMERIC)"
- " >= "
- " (($3::NUMERIC * 1000000) + $4::NUMERIC)"
- " + (SELECT COALESCE(SUM(total_locked::NUMERIC * 1000000"
- " + total_locked_frac::NUMERIC), 0)"
- " FROM merchant_inventory_locks mil"
- " WHERE mil.product_serial = tmp.product_serial)"
- " + (SELECT COALESCE(SUM(total_locked::NUMERIC * 1000000"
- " + total_locked_frac::NUMERIC), 0)"
- " FROM merchant_order_locks mol"
- " WHERE mol.product_serial = tmp.product_serial)"
- " ))");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- params);
-}
diff --git a/src/backenddb/mark_contract_paid.c b/src/backenddb/mark_contract_paid.c
@@ -1,107 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/mark_contract_paid.c
- * @brief Implementation of the mark_contract_paid function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/mark_contract_paid.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_mark_contract_paid (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- const char *session_id,
- int16_t choice_index)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_string (session_id),
- (choice_index >= 0)
- ? GNUNET_PQ_query_param_int16 (&choice_index)
- : GNUNET_PQ_query_param_null (),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_QueryParam uparams[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- /* Session ID must always be given by the caller. */
- GNUNET_assert (NULL != session_id);
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (instance_id,
- pg->current_merchant_id));
-
- /* FIXME: combine the 3 individual statements into a stored procedure! */
- /* no preflight check here, run in transaction by caller! */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Marking h_contract_terms '%s' of %s as paid for session `%s'\n",
- GNUNET_h2s (&h_contract_terms->hash),
- instance_id,
- session_id);
- TMH_PQ_prepare_anon (pg,
- "UPDATE merchant_contract_terms SET"
- " paid=TRUE"
- ",session_id=$2"
- ",choice_index=$3"
- " WHERE h_contract_terms=$1");
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- params);
- if (qs <= 0)
- return qs;
- TMH_PQ_prepare_anon (pg,
- "UPDATE merchant_inventory SET"
- " total_sold = total_sold"
- " + order_locks.total_locked"
- " + ((merchant_inventory.total_sold_frac::BIGINT"
- " + order_locks.total_locked_frac::BIGINT) / 1000000)"
- " ,total_sold_frac ="
- " ((merchant_inventory.total_sold_frac::BIGINT"
- " + order_locks.total_locked_frac::BIGINT) % 1000000)::INT4"
- " FROM (SELECT total_locked,total_locked_frac,product_serial"
- " FROM merchant_order_locks"
- " WHERE order_serial="
- " (SELECT order_serial"
- " FROM merchant_contract_terms"
- " WHERE h_contract_terms=$1)"
- " ) AS order_locks"
- " WHERE merchant_inventory.product_serial"
- " =order_locks.product_serial");
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- uparams);
- if (qs < 0)
- return qs; /* 0: no inventory management, that's OK! */
- /* ON DELETE CASCADE deletes from merchant_order_locks */
- TMH_PQ_prepare_anon (pg,
- "DELETE"
- " FROM merchant_orders"
- " WHERE order_serial="
- " (SELECT order_serial"
- " FROM merchant_contract_terms"
- " WHERE h_contract_terms=$1)");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- uparams);
-}
diff --git a/src/backenddb/mark_order_wired.c b/src/backenddb/mark_order_wired.c
@@ -1,45 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/mark_order_wired.c
- * @brief Implementation of the mark_order_wired function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/mark_order_wired.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_mark_order_wired (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- uint64_t order_serial)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&order_serial),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- TMH_PQ_prepare_anon (pg,
- "UPDATE merchant_contract_terms SET"
- " wired=TRUE"
- " WHERE order_serial=$1");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- params);
-}
diff --git a/src/backenddb/meson.build b/src/backenddb/meson.build
@@ -19,12 +19,12 @@ libtalermerchantdb = library(
'iterate_kyc_statuses.c',
'insert_kyc_failure.c',
'insert_kyc_status.c',
- 'activate_account.c',
+ 'do_insert_account.c',
'get_exists_transfer.c',
'delete_category.c',
'delete_contract_terms.c',
'delete_exchange_accounts.c',
- 'delete_instance_private_key.c',
+ 'update_to_instance_private_key_deleted.c',
'delete_login_token.c',
'delete_login_token_by_serial.c',
'delete_order.c',
@@ -36,13 +36,13 @@ libtalermerchantdb = library(
'delete_tos_accepted_early.c',
'delete_transfer.c',
'delete_webhook.c',
- 'expire_locks.c',
+ 'do_expire_locks.c',
'gc.c',
'get_kyc_limits.c',
'get_kyc_status.c',
- 'inactivate_account.c',
- 'increase_refund.c',
- 'increment_money_pots.c',
+ 'update_to_account_inactive.c',
+ 'do_increase_refund.c',
+ 'update_money_pot_totals.c',
'insert_account.c',
'insert_category.c',
'insert_unit.c',
@@ -76,9 +76,9 @@ libtalermerchantdb = library(
'iterate_custom_units_by_names.c',
'get_unit.c',
'get_mfa_challenge.c',
- 'solve_mfa_challenge.c',
+ 'do_solve_mfa_challenge.c',
'update_mfa_challenge.c',
- 'create_mfa_challenge.c',
+ 'insert_mfa_challenge.c',
'insert_report.c',
'delete_report.c',
'update_report.c',
@@ -100,7 +100,7 @@ libtalermerchantdb = library(
'get_missing_money_pot.c',
'iterate_money_pots.c',
'get_money_pot.c',
- 'lock_product.c',
+ 'insert_inventory_lock.c',
'get_account_serial.c',
'iterate_all_products.c',
'iterate_categories.c',
@@ -150,11 +150,11 @@ libtalermerchantdb = library(
'iterate_all_webhooks.c',
'iterate_webhooks.c',
'get_wire_fee.c',
- 'mark_contract_paid.c',
- 'mark_order_wired.c',
+ 'update_to_contract_terms_paid.c',
+ 'update_to_contract_terms_wired.c',
'iterate_order_blinded_sigs.c',
- 'purge_instance.c',
- 'refund_coin.c',
+ 'delete_instance.c',
+ 'insert_refund_by_coin.c',
'get_account.c',
'get_account_by_uri.c',
'iterate_accounts.c',
@@ -169,8 +169,8 @@ libtalermerchantdb = library(
'get_otp.c',
'get_otp_serial.c',
'iterate_wirewatch_accounts.c',
- 'store_wire_fee_by_exchange.c',
- 'unlock_inventory.c',
+ 'insert_wire_fee.c',
+ 'delete_inventory_lock.c',
'update_account.c',
'update_category.c',
'update_contract_session.c',
@@ -185,7 +185,7 @@ libtalermerchantdb = library(
'update_template.c',
'update_token_family.c',
'update_transfer_status.c',
- 'finalize_transfer_status.c',
+ 'update_to_transfer_finalized.c',
'delete_donau_instance.c',
'insert_order_blinded_sigs.c',
'update_webhook.c',
@@ -203,7 +203,7 @@ libtalermerchantdb = library(
'get_donau_keys.c',
'get_order_charity.c',
'get_tos_accepted_early.c',
- 'upsert_donau_keys.c',
+ 'insert_donau_keys.c',
'update_donau_instance.c',
'merchantdb_helper.c',
],
diff --git a/src/backenddb/purge_instance.c b/src/backenddb/purge_instance.c
@@ -1,52 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/purge_instance.c
- * @brief Implementation of the purge_instance function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/purge_instance.h"
-#include "helper.h"
-
-
-/**
- * Purge an instance and all associated information from our database.
- * Highly likely to cause undesired data loss. Use with caution.
- *
- * @param pg database context
- * @param merchant_id identifier of the instance
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_purge_instance (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *merchant_id)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (merchant_id),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (pg,
- "purge_instance",
- "DELETE FROM merchant.merchant_instances"
- " WHERE merchant_id = $1");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "purge_instance",
- params);
-}
diff --git a/src/backenddb/refund_coin.c b/src/backenddb/refund_coin.c
@@ -1,74 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/refund_coin.c
- * @brief Implementation of the refund_coin function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/refund_coin.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_refund_coin (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- 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)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_timestamp (&refund_timestamp),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_string (reason),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- GNUNET_assert (0 == strcmp (instance_id,
- pg->current_merchant_id));
- TMH_PQ_prepare_anon (pg,
- "INSERT INTO merchant_refunds"
- "(order_serial"
- ",rtransaction_id"
- ",refund_timestamp"
- ",coin_pub"
- ",reason"
- ",refund_amount"
- ") "
- "SELECT "
- " dcon.order_serial"
- ",0" /* rtransaction_id always 0 for /abort */
- ",$2"
- ",dep.coin_pub"
- ",$4"
- ",dep.amount_with_fee"
- " FROM merchant_deposits dep"
- " JOIN merchant_deposit_confirmations dcon"
- " USING (deposit_confirmation_serial)"
- " WHERE dep.coin_pub=$3"
- " AND dcon.order_serial="
- " (SELECT order_serial"
- " FROM merchant_contract_terms"
- " WHERE h_contract_terms=$1)");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- params);
-}
diff --git a/src/backenddb/solve_mfa_challenge.c b/src/backenddb/solve_mfa_challenge.c
@@ -1,80 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/solve_mfa_challenge.c
- * @brief Implementation of the solve_mfa_challenge function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "taler/taler_merchant_util.h"
-#include "merchant-database/solve_mfa_challenge.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_solve_mfa_challenge (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- uint64_t challenge_id,
- const struct TALER_MERCHANT_MFA_BodyHash *h_body,
- const char *solution,
- bool *solved,
- uint32_t *retry_counter)
-{
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
- bool no_match;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&challenge_id),
- GNUNET_PQ_query_param_auto_from_type (h_body),
- GNUNET_PQ_query_param_string (solution),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("out_solved",
- solved),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_uint32 ("out_retry_counter",
- retry_counter),
- &no_match),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- /* conservatively set security-relevant return values to
- safe values, even though these should not be used with qs <= 0 */
- *solved = false;
- *retry_counter = 0;
- TMH_PQ_prepare_anon (pg,
- "SELECT"
- " out_solved"
- " ,out_retry_counter"
- " FROM merchant.merchant_do_solve_mfa_challenge"
- " ($1, $2, $3, $4);");
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "",
- params,
- rs);
- if (qs <= 0)
- return qs;
- if (no_match)
- {
- GNUNET_PQ_cleanup_result (rs);
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
- GNUNET_PQ_cleanup_result (rs);
- return qs;
-}
diff --git a/src/backenddb/sql-schema/meson.build b/src/backenddb/sql-schema/meson.build
@@ -14,7 +14,7 @@ sql_global_procedures = [
'../iterate_wirewatch_accounts.sql',
'../iterate_open_transfers.sql',
'../iterate_all_donau_instances.sql',
- '../solve_mfa_challenge.sql',
+ '../do_solve_mfa_challenge.sql',
'../iterate_pending_deposits.sql',
'../iterate_reports_pending.sql',
'../pg_select_accounts.sql',
@@ -51,14 +51,14 @@ sql_instance_procedures = [
'../insert_kyc_failure.sql',
'../update_product_group.sql',
'../update_money_pot.sql',
- '../increment_money_pots.sql',
+ '../update_money_pot_totals.sql',
'../iterate_kyc_statuses.sql',
'../insert_transfer.sql',
'../insert_unclaim_signature.sql',
'../insert_deposit_confirmation.sql',
- '../activate_account.sql',
- '../inactivate_account.sql',
- '../expire_locks.sql',
+ '../do_insert_account.sql',
+ '../update_to_account_inactive.sql',
+ '../do_expire_locks.sql',
'../pg_merchant_send_account_notification.sql',
'../pg_merchant_account_trigger.sql',
'../pg_merchant_send_kyc_notification.sql',
diff --git a/src/backenddb/store_wire_fee_by_exchange.c b/src/backenddb/store_wire_fee_by_exchange.c
@@ -1,72 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/store_wire_fee_by_exchange.c
- * @brief Implementation of the store_wire_fee_by_exchange function for Postgres
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/store_wire_fee_by_exchange.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_store_wire_fee_by_exchange (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- 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)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (master_pub),
- GNUNET_PQ_query_param_auto_from_type (h_wire_method),
- TALER_PQ_query_param_amount_with_currency (pg->conn,
- &fees->wire),
- TALER_PQ_query_param_amount_with_currency (pg->conn,
- &fees->closing),
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_timestamp (&end_date),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_end
- };
-
- /* no preflight check here, run in its own transaction by the caller */
- PREPARE (pg,
- "insert_wire_fee",
- "INSERT INTO merchant.merchant_exchange_wire_fees"
- "(master_pub"
- ",h_wire_method"
- ",wire_fee"
- ",closing_fee"
- ",start_date"
- ",end_date"
- ",master_sig)"
- " VALUES "
- "($1, $2, $3, $4, $5, $6, $7)"
- " ON CONFLICT DO NOTHING");
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Storing wire fee for %s starting at %s of %s\n",
- TALER_B2S (master_pub),
- GNUNET_TIME_timestamp2s (start_date),
- TALER_amount2s (&fees->wire));
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_wire_fee",
- params);
-}
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
@@ -30,14 +30,14 @@
#include "merchant-database/iterate_kyc_statuses.h"
#include "merchant-database/insert_kyc_status.h"
#include "merchant-database/delete_contract_terms.h"
-#include "merchant-database/delete_instance_private_key.h"
+#include "merchant-database/update_to_instance_private_key_deleted.h"
#include "merchant-database/delete_order.h"
#include "merchant-database/delete_pending_webhook.h"
#include "merchant-database/delete_product.h"
#include "merchant-database/delete_template.h"
#include "merchant-database/delete_webhook.h"
-#include "merchant-database/inactivate_account.h"
-#include "merchant-database/increase_refund.h"
+#include "merchant-database/update_to_account_inactive.h"
+#include "merchant-database/do_increase_refund.h"
#include "merchant-database/insert_account.h"
#include "merchant-database/insert_contract_terms.h"
#include "merchant-database/insert_deposit.h"
@@ -55,7 +55,7 @@
#include "merchant-database/insert_transfer.h"
#include "merchant-database/insert_transfer_details.h"
#include "merchant-database/insert_webhook.h"
-#include "merchant-database/lock_product.h"
+#include "merchant-database/insert_inventory_lock.h"
#include "merchant-database/get_account_serial.h"
#include "merchant-database/get_contract_terms.h"
#include "merchant-database/get_contract_terms_status.h"
@@ -84,12 +84,12 @@
#include "merchant-database/iterate_webhooks_by_event.h"
#include "merchant-database/iterate_webhooks.h"
#include "merchant-database/get_wire_fee.h"
-#include "merchant-database/mark_contract_paid.h"
-#include "merchant-database/mark_order_wired.h"
-#include "merchant-database/refund_coin.h"
+#include "merchant-database/update_to_contract_terms_paid.h"
+#include "merchant-database/update_to_contract_terms_wired.h"
+#include "merchant-database/insert_refund_by_coin.h"
#include "merchant-database/set_instance.h"
-#include "merchant-database/store_wire_fee_by_exchange.h"
-#include "merchant-database/unlock_inventory.h"
+#include "merchant-database/insert_wire_fee.h"
+#include "merchant-database/delete_inventory_lock.h"
#include "merchant-database/update_contract_terms.h"
#include "merchant-database/update_instance.h"
#include "merchant-database/update_pending_webhook.h"
@@ -99,7 +99,7 @@
#include "merchant-database/create_tables.h"
#include "merchant-database/drop_tables.h"
#include "merchant-database/preflight.h"
-#include "merchant-database/purge_instance.h"
+#include "merchant-database/delete_instance.h"
/**
@@ -517,7 +517,7 @@ test_delete_instance_private_key (const struct InstanceData *instance,
{
TEST_SET_INSTANCE (instance->instance.id, expected_result);
TEST_COND_RET_ON_FAIL (expected_result ==
- TALER_MERCHANTDB_delete_instance_private_key (
+ TALER_MERCHANTDB_update_to_instance_private_key_deleted (
pg,
instance->instance.id),
"Delete instance private key failed\n");
@@ -538,8 +538,8 @@ test_purge_instance (const struct InstanceData *instance,
{
TEST_SET_INSTANCE (instance->instance.id, expected_result);
TEST_COND_RET_ON_FAIL (expected_result ==
- TALER_MERCHANTDB_purge_instance (pg,
- instance->instance.id),
+ TALER_MERCHANTDB_delete_instance (pg,
+ instance->instance.id),
"Purge instance failed\n");
return 0;
}
@@ -581,9 +581,9 @@ test_inactivate_account (const struct InstanceData *instance,
{
TEST_SET_INSTANCE (instance->instance.id, expected_result);
TEST_COND_RET_ON_FAIL (expected_result ==
- TALER_MERCHANTDB_inactivate_account (pg,
- instance->instance.id,
- &account->h_wire),
+ TALER_MERCHANTDB_update_to_account_inactive (pg,
+ instance->instance.id,
+ &account->h_wire),
"Deactivate account failed\n");
return 0;
}
@@ -1498,25 +1498,25 @@ run_test_products (struct TestProducts_Closure *cls)
cls->products));
/* Test locking */
uuid.value[0] = 0x1287346a;
- if (0 != TALER_MERCHANTDB_lock_product (pg,
- cls->instance.instance.id,
- cls->products[0].id,
- &uuid,
- 256,
- 0,
- refund_deadline))
+ if (0 != TALER_MERCHANTDB_insert_inventory_lock (pg,
+ cls->instance.instance.id,
+ cls->products[0].id,
+ &uuid,
+ 256,
+ 0,
+ refund_deadline))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lock product failed\n");
return 1;
}
- if (1 != TALER_MERCHANTDB_lock_product (pg,
- cls->instance.instance.id,
- cls->products[0].id,
- &uuid,
- 1,
- 0,
- refund_deadline))
+ if (1 != TALER_MERCHANTDB_insert_inventory_lock (pg,
+ cls->instance.instance.id,
+ cls->products[0].id,
+ &uuid,
+ 1,
+ 0,
+ refund_deadline))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lock product failed\n");
@@ -1538,28 +1538,28 @@ run_test_products (struct TestProducts_Closure *cls)
1,
cls->products));
/* Test unlocking */
- if (1 != TALER_MERCHANTDB_unlock_inventory (pg,
- &uuid))
+ if (1 != TALER_MERCHANTDB_delete_inventory_lock (pg,
+ &uuid))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unlock inventory failed\n");
return 1;
}
- if (0 != TALER_MERCHANTDB_unlock_inventory (pg,
- &uuid))
+ if (0 != TALER_MERCHANTDB_delete_inventory_lock (pg,
+ &uuid))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unlock inventory failed\n");
return 1;
}
/* Re-lock products[0] to exercise deletion of a locked product */
- if (1 != TALER_MERCHANTDB_lock_product (pg,
- cls->instance.instance.id,
- cls->products[0].id,
- &uuid,
- 1,
- 0,
- refund_deadline))
+ if (1 != TALER_MERCHANTDB_insert_inventory_lock (pg,
+ cls->instance.instance.id,
+ cls->products[0].id,
+ &uuid,
+ 1,
+ 0,
+ refund_deadline))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Lock product failed\n");
@@ -2137,11 +2137,11 @@ test_mark_contract_paid (const struct InstanceData *instance,
&h_contract_terms));
TEST_SET_INSTANCE (instance->instance.id, expected_result);
TEST_COND_RET_ON_FAIL (expected_result ==
- TALER_MERCHANTDB_mark_contract_paid (pg,
- instance->instance.id,
- &h_contract_terms,
- "test_orders_session",
- -1),
+ TALER_MERCHANTDB_update_to_contract_terms_paid (pg,
+ instance->instance.id,
+ &h_contract_terms,
+ "test_orders_session",
+ -1),
"Mark contract paid failed\n");
return 0;
}
@@ -2309,8 +2309,8 @@ test_mark_order_wired (uint64_t order_id,
enum GNUNET_DB_QueryStatus expected_result)
{
TEST_COND_RET_ON_FAIL (expected_result ==
- TALER_MERCHANTDB_mark_order_wired (pg,
- order_id),
+ TALER_MERCHANTDB_update_to_contract_terms_wired (pg,
+ order_id),
"Mark order wired failed\n");
return 0;
}
@@ -4165,7 +4165,7 @@ test_insert_wire_fee (const struct ExchangeSignkeyData *signkey,
enum GNUNET_DB_QueryStatus expected_result)
{
TEST_COND_RET_ON_FAIL (expected_result ==
- TALER_MERCHANTDB_store_wire_fee_by_exchange (
+ TALER_MERCHANTDB_insert_wire_fee (
pg,
&signkey->master_pub,
&wire_fee->h_wire_method,
@@ -5364,26 +5364,26 @@ run_test_refunds (struct TestRefunds_Closure *cls)
GNUNET_DB_STATUS_SUCCESS_ONE_RESULT));
/* Test refund coin */
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
- TALER_MERCHANTDB_refund_coin (pg,
- cls->instance.instance.id,
- &cls->deposits[0].h_contract_terms
- ,
- cls->refunds[0].timestamp,
- cls->refunds[0].coin_pub,
- cls->refunds[0].reason),
+ TALER_MERCHANTDB_insert_refund_by_coin (pg,
+ cls->instance.instance.id,
+ &cls->deposits[0].h_contract_terms
+ ,
+ cls->refunds[0].timestamp,
+ cls->refunds[0].coin_pub,
+ cls->refunds[0].reason),
"Refund coin failed\n");
refund_serial = get_refund_serial (&cls->instance,
&cls->deposits[0].h_contract_terms,
&cls->refunds[0]);
/* Test double refund fails */
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS ==
- TALER_MERCHANTDB_refund_coin (pg,
- cls->instance.instance.id,
- &cls->deposits[0].h_contract_terms
- ,
- cls->refunds[0].timestamp,
- cls->refunds[0].coin_pub,
- cls->refunds[0].reason),
+ TALER_MERCHANTDB_insert_refund_by_coin (pg,
+ cls->instance.instance.id,
+ &cls->deposits[0].h_contract_terms
+ ,
+ cls->refunds[0].timestamp,
+ cls->refunds[0].coin_pub,
+ cls->refunds[0].reason),
"Refund coin failed\n");
/* Test lookup refunds */
TEST_RET_ON_FAIL (test_lookup_refunds (&cls->instance,
@@ -5420,26 +5420,26 @@ run_test_refunds (struct TestRefunds_Closure *cls)
TALER_string_to_amount ("EUR:1000.00",
&inc));
TEST_COND_RET_ON_FAIL (TALER_MERCHANTDB_RS_TOO_HIGH ==
- TALER_MERCHANTDB_increase_refund (pg,
- cls->instance.instance.id,
- cls->orders[0].id,
- &inc,
- NULL,
- NULL,
- "more"),
+ TALER_MERCHANTDB_do_increase_refund (pg,
+ cls->instance.instance.id,
+ cls->orders[0].id,
+ &inc,
+ NULL,
+ NULL,
+ "more"),
"Increase refund failed\n");
/* Test increase refund */
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:1.00",
&inc));
TEST_COND_RET_ON_FAIL (TALER_MERCHANTDB_RS_SUCCESS ==
- TALER_MERCHANTDB_increase_refund (pg,
- cls->instance.instance.id,
- cls->orders[0].id,
- &inc,
- NULL,
- NULL,
- "more"),
+ TALER_MERCHANTDB_do_increase_refund (pg,
+ cls->instance.instance.id,
+ cls->orders[0].id,
+ &inc,
+ NULL,
+ NULL,
+ "more"),
"Increase refund failed\n");
/* Test lookup refund proof */
TEST_RET_ON_FAIL (test_lookup_refund_proof (1,
@@ -5463,25 +5463,25 @@ run_test_refunds (struct TestRefunds_Closure *cls)
TALER_string_to_amount ("EUR:10.00",
&inc));
TEST_COND_RET_ON_FAIL (TALER_MERCHANTDB_RS_SUCCESS ==
- TALER_MERCHANTDB_increase_refund (pg,
- cls->instance.instance.id,
- cls->orders[1].id,
- &inc,
- NULL,
- NULL,
- cls->refunds[1].reason),
+ TALER_MERCHANTDB_do_increase_refund (pg,
+ cls->instance.instance.id,
+ cls->orders[1].id,
+ &inc,
+ NULL,
+ NULL,
+ cls->refunds[1].reason),
"Increase refund failed\n");
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:20.00",
&inc));
TEST_COND_RET_ON_FAIL (TALER_MERCHANTDB_RS_SUCCESS ==
- TALER_MERCHANTDB_increase_refund (pg,
- cls->instance.instance.id,
- cls->orders[1].id,
- &inc,
- NULL,
- NULL,
- cls->refunds[2].reason),
+ TALER_MERCHANTDB_do_increase_refund (pg,
+ cls->instance.instance.id,
+ cls->orders[1].id,
+ &inc,
+ NULL,
+ NULL,
+ cls->refunds[2].reason),
"Increase refund failed\n");
TEST_RET_ON_FAIL (test_lookup_refunds_detailed (&cls->instance,
&cls->deposits[2].
@@ -5694,13 +5694,13 @@ run_test_lookup_orders_all_filters (
&cls->deposits[i],
GNUNET_DB_STATUS_SUCCESS_ONE_RESULT));
TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
- TALER_MERCHANTDB_refund_coin (pg,
- cls->instance.instance.id,
- &cls->deposits[i].
- h_contract_terms,
- cls->refunds[i].timestamp,
- cls->refunds[i].coin_pub,
- cls->refunds[i].reason),
+ TALER_MERCHANTDB_insert_refund_by_coin (pg,
+ cls->instance.instance.id,
+ &cls->deposits[i].
+ h_contract_terms,
+ cls->refunds[i].timestamp,
+ cls->refunds[i].coin_pub,
+ cls->refunds[i].reason),
"Refund coin failed\n");
}
diff --git a/src/backenddb/unlock_inventory.c b/src/backenddb/unlock_inventory.c
@@ -1,45 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/unlock_inventory.c
- * @brief Implementation of the unlock_inventory function for Postgres
- * @author Iván Ávalos
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "merchant-database/unlock_inventory.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_unlock_inventory (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const struct GNUNET_Uuid *uuid)
-{
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (uuid),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (NULL != pg->current_merchant_id);
- TMH_PQ_prepare_anon (pg,
- "DELETE"
- " FROM merchant_inventory_locks"
- " WHERE lock_uuid=$1");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "",
- params);
-}
diff --git a/src/backenddb/update_money_pot_totals.c b/src/backenddb/update_money_pot_totals.c
@@ -0,0 +1,76 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/update_money_pot_totals.c
+ * @brief Implementation of the update_money_pot_totals function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_error_codes.h>
+#include <taler/taler_dbevents.h>
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/update_money_pot_totals.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_money_pot_totals (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ size_t money_pots_len,
+ const uint64_t *money_pot_ids,
+ const struct TALER_Amount *pot_increments)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_array_uint64 (money_pots_len,
+ money_pot_ids,
+ pg->conn),
+ TALER_PQ_query_param_array_amount_with_currency (money_pots_len,
+ pot_increments,
+ "merchant",
+ pg->conn),
+ GNUNET_PQ_query_param_end
+ };
+ bool not_found;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("not_found",
+ ¬_found),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (instance_id,
+ pg->current_merchant_id));
+ TMH_PQ_prepare_anon (pg,
+ "SELECT"
+ " out_not_found AS not_found"
+ " FROM merchant_do_increment_money_pots"
+ "($1,$2);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "",
+ params,
+ rs);
+ GNUNET_PQ_cleanup_query_params_closures (params);
+ if (qs <= 0)
+ return qs;
+ if (not_found)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Some money pots could not be implemented because they no longer exist. This is not a bug and expected to happen if a merchant deletes money pots that were used in orders active at the time.\n");
+ }
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+}
diff --git a/src/backenddb/increment_money_pots.sql b/src/backenddb/update_money_pot_totals.sql
diff --git a/src/backenddb/update_to_account_inactive.c b/src/backenddb/update_to_account_inactive.c
@@ -0,0 +1,61 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/update_to_account_inactive.c
+ * @brief Implementation of the update_to_account_inactive function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/update_to_account_inactive.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_account_inactive (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *merchant_id,
+ const struct TALER_MerchantWireHashP *h_wire)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_wire),
+ GNUNET_PQ_query_param_end
+ };
+ bool found;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("found",
+ &found),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (merchant_id,
+ pg->current_merchant_id));
+ TMH_PQ_prepare_anon (pg,
+ "SELECT out_found AS found"
+ " FROM merchant_do_inactivate_account"
+ " ($1);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "",
+ params,
+ rs);
+ if (qs < 0)
+ return qs;
+ if (! found)
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ return qs;
+}
diff --git a/src/backenddb/inactivate_account.sql b/src/backenddb/update_to_account_inactive.sql
diff --git a/src/backenddb/update_to_contract_terms_paid.c b/src/backenddb/update_to_contract_terms_paid.c
@@ -0,0 +1,107 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/update_to_contract_terms_paid.c
+ * @brief Implementation of the update_to_contract_terms_paid function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/update_to_contract_terms_paid.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_contract_terms_paid (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const char *session_id,
+ int16_t choice_index)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+ GNUNET_PQ_query_param_string (session_id),
+ (choice_index >= 0)
+ ? GNUNET_PQ_query_param_int16 (&choice_index)
+ : GNUNET_PQ_query_param_null (),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_QueryParam uparams[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+ GNUNET_PQ_query_param_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ /* Session ID must always be given by the caller. */
+ GNUNET_assert (NULL != session_id);
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ GNUNET_assert (0 == strcmp (instance_id,
+ pg->current_merchant_id));
+
+ /* FIXME: combine the 3 individual statements into a stored procedure! */
+ /* no preflight check here, run in transaction by caller! */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Marking h_contract_terms '%s' of %s as paid for session `%s'\n",
+ GNUNET_h2s (&h_contract_terms->hash),
+ instance_id,
+ session_id);
+ TMH_PQ_prepare_anon (pg,
+ "UPDATE merchant_contract_terms SET"
+ " paid=TRUE"
+ ",session_id=$2"
+ ",choice_index=$3"
+ " WHERE h_contract_terms=$1");
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ params);
+ if (qs <= 0)
+ return qs;
+ TMH_PQ_prepare_anon (pg,
+ "UPDATE merchant_inventory SET"
+ " total_sold = total_sold"
+ " + order_locks.total_locked"
+ " + ((merchant_inventory.total_sold_frac::BIGINT"
+ " + order_locks.total_locked_frac::BIGINT) / 1000000)"
+ " ,total_sold_frac ="
+ " ((merchant_inventory.total_sold_frac::BIGINT"
+ " + order_locks.total_locked_frac::BIGINT) % 1000000)::INT4"
+ " FROM (SELECT total_locked,total_locked_frac,product_serial"
+ " FROM merchant_order_locks"
+ " WHERE order_serial="
+ " (SELECT order_serial"
+ " FROM merchant_contract_terms"
+ " WHERE h_contract_terms=$1)"
+ " ) AS order_locks"
+ " WHERE merchant_inventory.product_serial"
+ " =order_locks.product_serial");
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ uparams);
+ if (qs < 0)
+ return qs; /* 0: no inventory management, that's OK! */
+ /* ON DELETE CASCADE deletes from merchant_order_locks */
+ TMH_PQ_prepare_anon (pg,
+ "DELETE"
+ " FROM merchant_orders"
+ " WHERE order_serial="
+ " (SELECT order_serial"
+ " FROM merchant_contract_terms"
+ " WHERE h_contract_terms=$1)");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ uparams);
+}
diff --git a/src/backenddb/update_to_contract_terms_wired.c b/src/backenddb/update_to_contract_terms_wired.c
@@ -0,0 +1,45 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2023 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/update_to_contract_terms_wired.c
+ * @brief Implementation of the update_to_contract_terms_wired function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/update_to_contract_terms_wired.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_contract_terms_wired (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ uint64_t order_serial)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&order_serial),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ TMH_PQ_prepare_anon (pg,
+ "UPDATE merchant_contract_terms SET"
+ " wired=TRUE"
+ " WHERE order_serial=$1");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "",
+ params);
+}
diff --git a/src/backenddb/update_to_instance_private_key_deleted.c b/src/backenddb/update_to_instance_private_key_deleted.c
@@ -0,0 +1,45 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/update_to_instance_private_key_deleted.c
+ * @brief Implementation of the update_to_instance_private_key_deleted function for Postgres
+ * @author Iván Ávalos
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/update_to_instance_private_key_deleted.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_instance_private_key_deleted (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *merchant_id)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (merchant_id),
+ GNUNET_PQ_query_param_end
+ };
+
+ PREPARE (pg,
+ "delete_instance_private_key",
+ "UPDATE merchant.merchant_instances"
+ " SET merchant_priv = NULL"
+ " WHERE merchant_id = $1");
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "delete_instance_private_key",
+ params);
+}
diff --git a/src/backenddb/update_to_transfer_finalized.c b/src/backenddb/update_to_transfer_finalized.c
@@ -0,0 +1,76 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/backenddb/update_to_transfer_finalized.c
+ * @brief Implementation of the update_to_transfer_finalized function for Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <taler/taler_pq_lib.h>
+#include "merchant-database/update_to_transfer_finalized.h"
+#include "helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_transfer_finalized (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *exchange_url,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct GNUNET_HashCode *h_details,
+ const struct TALER_Amount *total_amount,
+ const struct TALER_Amount *wire_fee,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (wtid),
+ GNUNET_PQ_query_param_string (exchange_url),
+ TALER_PQ_query_param_amount_with_currency (pg->conn,
+ total_amount),
+ TALER_PQ_query_param_amount_with_currency (pg->conn,
+ wire_fee),
+ GNUNET_PQ_query_param_auto_from_type (h_details),
+ GNUNET_PQ_query_param_auto_from_type (exchange_pub),
+ GNUNET_PQ_query_param_auto_from_type (exchange_sig),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (NULL != pg->current_merchant_id);
+ TMH_PQ_prepare_anon (pg,
+ "WITH subquery AS ("
+ " SELECT signkey_serial"
+ " FROM merchant.merchant_exchange_signing_keys"
+ " WHERE exchange_pub=$6"
+ ")"
+ "UPDATE merchant_expected_transfers SET"
+ " last_http_status=200"
+ ",last_ec=0"
+ ",last_detail=NULL"
+ ",retry_needed=FALSE"
+ ",retry_time=0"
+ ",expected_credit_amount=$3"
+ ",wire_fee=$4"
+ ",h_details=$5"
+ ",signkey_serial=subquery.signkey_serial"
+ ",exchange_sig=$7"
+ " FROM subquery"
+ " WHERE wtid=$1"
+ " AND exchange_url=$2");
+ return GNUNET_PQ_eval_prepared_non_select (
+ pg->conn,
+ "",
+ params);
+}
diff --git a/src/backenddb/upsert_donau_keys.c b/src/backenddb/upsert_donau_keys.c
@@ -1,70 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2024 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/backenddb/upsert_donau_keys.c
- * @brief Implementation of the upsert_donau_keys function for Postgres
- * @author Bohdan Potuzhnyi
- * @author Vlada Svirsh
- */
-#include "platform.h"
-#include <taler/taler_pq_lib.h>
-#include "donau/donau_service.h"
-#include "merchant-database/upsert_donau_keys.h"
-#include "helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_upsert_donau_keys (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const struct DONAU_Keys *keys,
- struct GNUNET_TIME_Absolute first_retry)
-{
- enum GNUNET_DB_QueryStatus qs;
- json_t *jkeys = DONAU_keys_to_json (keys);
-
- if (NULL == jkeys)
- return GNUNET_DB_STATUS_HARD_ERROR;
-
- {
- struct GNUNET_PQ_QueryParam params[] = {
- TALER_PQ_query_param_json (jkeys),
- GNUNET_PQ_query_param_absolute_time (&first_retry),
- GNUNET_PQ_query_param_string (keys->donau_url),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (pg,
- "insert_donau_keys",
- "INSERT INTO merchant.merchant_donau_keys"
- " (keys_json"
- " ,first_retry"
- " ,donau_url"
- " ) VALUES ("
- " $1::TEXT::JSONB"
- " ,$2"
- " ,$3)"
- " ON CONFLICT (donau_url)"
- " DO UPDATE SET"
- " keys_json=EXCLUDED.keys_json,"
- " first_retry=EXCLUDED.first_retry;");
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_donau_keys",
- params);
- }
-
- json_decref (jkeys);
- return qs;
-}
diff --git a/src/include/merchant-database/activate_account.h b/src/include/merchant-database/activate_account.h
@@ -1,50 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/activate_account.h
- * @brief implementation of the activate_account function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_ACTIVATE_ACCOUNT_H
-#define MERCHANT_DATABASE_ACTIVATE_ACCOUNT_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Insert account or set an instance's
- * existing account in our database to "active".
- *
- * @param pg database context
- * @param account_details details of the account to actiate
- * @param[out] h_wire set to the hash of the salted payto URI
- * @param[out] salt set to salt used for computing @a h_wire
- * @param[out] not_found set to true if the instance was not found
- * @param[out] conflict set to true if a conflicting account is active
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_activate_account (struct TALER_MERCHANTDB_PostgresContext *pg,
- const struct TALER_MERCHANTDB_AccountDetails *account_details,
- struct TALER_MerchantWireHashP *h_wire,
- struct TALER_WireSaltP *salt,
- bool *not_found,
- bool *conflict);
-
-#endif
diff --git a/src/include/merchant-database/all.h b/src/include/merchant-database/all.h
@@ -8,18 +8,18 @@
#include "merchant-database/iterate_kyc_statuses.h"
#include "merchant-database/insert_kyc_failure.h"
#include "merchant-database/insert_kyc_status.h"
-#include "merchant-database/activate_account.h"
+#include "merchant-database/do_insert_account.h"
#include "merchant-database/get_exists_donau_instance.h"
#include "merchant-database/get_missing_money_pot.h"
#include "merchant-database/get_report_by_token.h"
#include "merchant-database/get_exists_transfer.h"
-#include "merchant-database/create_mfa_challenge.h"
+#include "merchant-database/insert_mfa_challenge.h"
#include "merchant-database/create_tables.h"
#include "merchant-database/delete_category.h"
#include "merchant-database/delete_contract_terms.h"
#include "merchant-database/delete_donau_instance.h"
#include "merchant-database/delete_exchange_accounts.h"
-#include "merchant-database/delete_instance_private_key.h"
+#include "merchant-database/update_to_instance_private_key_deleted.h"
#include "merchant-database/delete_login_token.h"
#include "merchant-database/delete_login_token_by_serial.h"
#include "merchant-database/delete_money_pot.h"
@@ -38,14 +38,14 @@
#include "merchant-database/drop_tables.h"
#include "merchant-database/event_listen.h"
#include "merchant-database/event_notify.h"
-#include "merchant-database/expire_locks.h"
-#include "merchant-database/finalize_transfer_status.h"
+#include "merchant-database/do_expire_locks.h"
+#include "merchant-database/update_to_transfer_finalized.h"
#include "merchant-database/gc.h"
#include "merchant-database/get_kyc_limits.h"
#include "merchant-database/get_kyc_status.h"
-#include "merchant-database/inactivate_account.h"
-#include "merchant-database/increase_refund.h"
-#include "merchant-database/increment_money_pots.h"
+#include "merchant-database/update_to_account_inactive.h"
+#include "merchant-database/do_increase_refund.h"
+#include "merchant-database/update_money_pot_totals.h"
#include "merchant-database/insert_account.h"
#include "merchant-database/insert_category.h"
#include "merchant-database/insert_contract_terms.h"
@@ -79,7 +79,7 @@
#include "merchant-database/insert_unclaim_signature.h"
#include "merchant-database/insert_unit.h"
#include "merchant-database/insert_webhook.h"
-#include "merchant-database/lock_product.h"
+#include "merchant-database/insert_inventory_lock.h"
#include "merchant-database/get_account_serial.h"
#include "merchant-database/iterate_all_products.h"
#include "merchant-database/iterate_all_webhooks.h"
@@ -142,11 +142,11 @@
#include "merchant-database/iterate_webhooks_by_event.h"
#include "merchant-database/iterate_webhooks.h"
#include "merchant-database/get_wire_fee.h"
-#include "merchant-database/mark_contract_paid.h"
-#include "merchant-database/mark_order_wired.h"
+#include "merchant-database/update_to_contract_terms_paid.h"
+#include "merchant-database/update_to_contract_terms_wired.h"
#include "merchant-database/preflight.h"
-#include "merchant-database/purge_instance.h"
-#include "merchant-database/refund_coin.h"
+#include "merchant-database/delete_instance.h"
+#include "merchant-database/insert_refund_by_coin.h"
#include "merchant-database/get_account.h"
#include "merchant-database/get_account_by_uri.h"
#include "merchant-database/iterate_accounts.h"
@@ -173,10 +173,10 @@
#include "merchant-database/get_unit.h"
#include "merchant-database/iterate_wirewatch_accounts.h"
#include "merchant-database/set_instance.h"
-#include "merchant-database/solve_mfa_challenge.h"
+#include "merchant-database/do_solve_mfa_challenge.h"
#include "merchant-database/start.h"
-#include "merchant-database/store_wire_fee_by_exchange.h"
-#include "merchant-database/unlock_inventory.h"
+#include "merchant-database/insert_wire_fee.h"
+#include "merchant-database/delete_inventory_lock.h"
#include "merchant-database/update_account.h"
#include "merchant-database/update_category.h"
#include "merchant-database/update_contract_session.h"
@@ -200,6 +200,6 @@
#include "merchant-database/update_unit.h"
#include "merchant-database/update_webhook.h"
#include "merchant-database/update_wirewatch_progress.h"
-#include "merchant-database/upsert_donau_keys.h"
+#include "merchant-database/insert_donau_keys.h"
#endif
diff --git a/src/include/merchant-database/create_mfa_challenge.h b/src/include/merchant-database/create_mfa_challenge.h
@@ -1,63 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/create_mfa_challenge.h
- * @brief implementation of the create_mfa_challenge function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_CREATE_MFA_CHALLENGE_H
-#define MERCHANT_DATABASE_CREATE_MFA_CHALLENGE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-/**
- * Create new multi-factor authorization (MFA) challenge in the database.
- *
- * @param pg database context
- * @param instance_name name of the instance impacted by the challenge;
- * used when communicating with the user; instance does not yet
- * need to exist (as it might be we are creating it!)
- * @param op operation that triggered the MFA request
- * @param h_body hash of the request body
- * @param salt salt used to compute @a h_body
- * @param code challenge code sent to the user
- * @param expiration_date when should the challenge expire
- * @param retransmission_date when do we next allow retransmission
- * of the challenge
- * @param tan_channel which channel was used
- * @param required_address address
- * where the challenge is to be sent
- * @param[out] challenge_id set to the ID of the new challenge
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_create_mfa_challenge (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_name,
- enum TALER_MERCHANT_MFA_CriticalOperation op,
- const struct TALER_MERCHANT_MFA_BodyHash *h_body,
- const struct TALER_MERCHANT_MFA_BodySalt *salt,
- const char *code,
- struct GNUNET_TIME_Absolute expiration_date,
- struct GNUNET_TIME_Absolute retransmission_date,
- enum TALER_MERCHANT_MFA_Channel tan_channel,
- const char *required_address,
- uint64_t *challenge_id);
-
-#endif
diff --git a/src/include/merchant-database/delete_instance.h b/src/include/merchant-database/delete_instance.h
@@ -0,0 +1,42 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/delete_instance.h
+ * @brief implementation of the delete_instance function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_DELETE_INSTANCE_H
+#define MERCHANT_DATABASE_DELETE_INSTANCE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+/**
+ * Purge an instance and all associated information from our database.
+ * Highly likely to cause undesired data loss. Use with caution.
+ *
+ * @param pg database context
+ * @param merchant_id identifier of the instance
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_delete_instance (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *merchant_id);
+
+#endif
diff --git a/src/include/merchant-database/delete_instance_private_key.h b/src/include/merchant-database/delete_instance_private_key.h
@@ -1,41 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/delete_instance_private_key.h
- * @brief implementation of the delete_instance_private_key function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_DELETE_INSTANCE_PRIVATE_KEY_H
-#define MERCHANT_DATABASE_DELETE_INSTANCE_PRIVATE_KEY_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Delete private key of an instance from our database.
- *
- * @param pg database context
- * @param merchant_id identifier of the instance
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_delete_instance_private_key (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *merchant_id);
-
-#endif
diff --git a/src/include/merchant-database/delete_inventory_lock.h b/src/include/merchant-database/delete_inventory_lock.h
@@ -0,0 +1,44 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/delete_inventory_lock.h
+ * @brief implementation of the delete_inventory_lock function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_DELETE_INVENTORY_LOCK_H
+#define MERCHANT_DATABASE_DELETE_INVENTORY_LOCK_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Release an inventory lock by UUID. Releases ALL stocks locked under
+ * the given UUID.
+ *
+ * @param pg database context
+ * @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
+TALER_MERCHANTDB_delete_inventory_lock (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const struct GNUNET_Uuid *uuid);
+
+#endif
diff --git a/src/include/merchant-database/do_expire_locks.h b/src/include/merchant-database/do_expire_locks.h
@@ -0,0 +1,41 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/do_do_expire_locks.h
+ * @brief implementation of the do_expire_locks function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_DO_EXPIRE_LOCKS_H
+#define MERCHANT_DATABASE_DO_EXPIRE_LOCKS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Release all expired product locks, including
+ * those from expired offers -- across all
+ * instances.
+ *
+ * @param pg database context
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_do_expire_locks (struct TALER_MERCHANTDB_PostgresContext *pg);
+
+#endif
diff --git a/src/include/merchant-database/do_increase_refund.h b/src/include/merchant-database/do_increase_refund.h
@@ -0,0 +1,79 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/do_do_increase_refund.h
+ * @brief implementation of the do_increase_refund function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_DO_INCREASE_REFUND_H
+#define MERCHANT_DATABASE_DO_INCREASE_REFUND_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/* Callback typedefs */
+/**
+ * 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);
+
+/**
+ * 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 mulrewardle SQL statements.
+ *
+ * @param pg database context
+ * @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
+TALER_MERCHANTDB_do_increase_refund (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ const char *order_id,
+ const struct TALER_Amount *refund,
+ TALER_MERCHANTDB_OperationLimitCallback olc,
+ void *olc_cls,
+ const char *reason);
+
+
+#endif
diff --git a/src/include/merchant-database/do_insert_account.h b/src/include/merchant-database/do_insert_account.h
@@ -0,0 +1,50 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/do_insert_account.h
+ * @brief implementation of the do_insert_account function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_DO_INSERT_ACCOUNT_H
+#define MERCHANT_DATABASE_DO_INSERT_ACCOUNT_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Insert account or set an instance's
+ * existing account in our database to "active".
+ *
+ * @param pg database context
+ * @param account_details details of the account to actiate
+ * @param[out] h_wire set to the hash of the salted payto URI
+ * @param[out] salt set to salt used for computing @a h_wire
+ * @param[out] not_found set to true if the instance was not found
+ * @param[out] conflict set to true if a conflicting account is active
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_do_insert_account (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const struct TALER_MERCHANTDB_AccountDetails *account_details,
+ struct TALER_MerchantWireHashP *h_wire,
+ struct TALER_WireSaltP *salt,
+ bool *not_found,
+ bool *conflict);
+
+#endif
diff --git a/src/include/merchant-database/do_solve_mfa_challenge.h b/src/include/merchant-database/do_solve_mfa_challenge.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/do_do_solve_mfa_challenge.h
+ * @brief implementation of the do_solve_mfa_challenge function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_DO_SOLVE_MFA_CHALLENGE_H
+#define MERCHANT_DATABASE_DO_SOLVE_MFA_CHALLENGE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Attempt to solve new multi-factor authorization (MFA) challenge.
+ * Checks the solution against the code in the database and updates
+ * the solution state and (on failure) retry counter depending on
+ * the result.
+ *
+ * @param pg database context
+ * @param challenge_id challenge ID to be solved
+ * @param h_body body of the operation the challenge authorizes
+ * @param solution proposed solution to be checked against the actual code
+ * @param[out] solved set to true if the challenge was solved by
+ * @a solution
+ * @param[out] retry_counter set to the number of attempts that remain
+ * for solving the challenge (after this time)
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_do_solve_mfa_challenge (struct TALER_MERCHANTDB_PostgresContext *pg,
+ uint64_t challenge_id,
+ const struct TALER_MERCHANT_MFA_BodyHash *h_body,
+ const char *solution,
+ bool *solved,
+ uint32_t *retry_counter);
+
+#endif
diff --git a/src/include/merchant-database/expire_locks.h b/src/include/merchant-database/expire_locks.h
@@ -1,41 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/expire_locks.h
- * @brief implementation of the expire_locks function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_EXPIRE_LOCKS_H
-#define MERCHANT_DATABASE_EXPIRE_LOCKS_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Release all expired product locks, including
- * those from expired offers -- across all
- * instances.
- *
- * @param pg database context
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_expire_locks (struct TALER_MERCHANTDB_PostgresContext *pg);
-
-#endif
diff --git a/src/include/merchant-database/finalize_transfer_status.h b/src/include/merchant-database/finalize_transfer_status.h
@@ -1,54 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/finalize_transfer_status.h
- * @brief implementation of the finalize_transfer_status function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_FINALIZE_TRANSFER_STATUS_H
-#define MERCHANT_DATABASE_FINALIZE_TRANSFER_STATUS_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Finalize transfer status.
- *
- * @param pg database context
- * @param exchange_url the exchange that made the transfer
- * @param wtid wire transfer subject
- * @param h_details hash over all of the aggregated deposits
- * @param total_amount total amount exchange claimed to have transferred
- * @param wire_fee wire fee charged by the exchange
- * @param exchange_pub key used to make @e exchange_sig
- * @param exchange_sig signature of the exchange over reconciliation data
- * @return database transaction status
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_finalize_transfer_status (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *exchange_url,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct GNUNET_HashCode *h_details,
- const struct TALER_Amount *total_amount,
- const struct TALER_Amount *wire_fee,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_ExchangeSignatureP *exchange_sig);
-
-
-#endif
diff --git a/src/include/merchant-database/inactivate_account.h b/src/include/merchant-database/inactivate_account.h
@@ -1,44 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/inactivate_account.h
- * @brief implementation of the inactivate_account function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_INACTIVATE_ACCOUNT_H
-#define MERCHANT_DATABASE_INACTIVATE_ACCOUNT_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Set an instance's account in our database to "inactive".
- *
- * @param pg database context
- * @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
-TALER_MERCHANTDB_inactivate_account (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *merchant_id,
- const struct TALER_MerchantWireHashP *h_wire);
-
-
-#endif
diff --git a/src/include/merchant-database/increase_refund.h b/src/include/merchant-database/increase_refund.h
@@ -1,79 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/increase_refund.h
- * @brief implementation of the increase_refund function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_INCREASE_REFUND_H
-#define MERCHANT_DATABASE_INCREASE_REFUND_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/* Callback typedefs */
-/**
- * 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);
-
-/**
- * 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 mulrewardle SQL statements.
- *
- * @param pg database context
- * @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
-TALER_MERCHANTDB_increase_refund (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- const char *order_id,
- const struct TALER_Amount *refund,
- TALER_MERCHANTDB_OperationLimitCallback olc,
- void *olc_cls,
- const char *reason);
-
-
-#endif
diff --git a/src/include/merchant-database/increment_money_pots.h b/src/include/merchant-database/increment_money_pots.h
@@ -1,50 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/increment_money_pots.h
- * @brief implementation of the increment_money_pots function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_INCREMENT_MONEY_POTS_H
-#define MERCHANT_DATABASE_INCREMENT_MONEY_POTS_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Increment amounts in money pots. If a money pot does not exist,
- * it is simply skipped (without causing an error!).
- *
- * @param pg database context
- * @param instance_id instance to update money pot for
- * @param money_pots_len length of the @a money_pots_ids
- * and @a pot_increments arrays
- * @param money_pot_ids serial numbers of the pots to increment
- * @param pot_increments new amounts to add to the respective pot
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_increment_money_pots (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- size_t money_pots_len,
- const uint64_t *money_pot_ids,
- const struct TALER_Amount *pot_increments);
-
-
-#endif
diff --git a/src/include/merchant-database/insert_donau_keys.h b/src/include/merchant-database/insert_donau_keys.h
@@ -0,0 +1,46 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/insert_donau_keys.h
+ * @brief implementation of the insert_donau_keys function for Postgres
+ * @author Bohdan Potuzhnyi
+ * @author Vlada Svirsh
+ */
+#ifndef MERCHANT_DATABASE_INSERT_DONAU_KEYS_H
+#define MERCHANT_DATABASE_INSERT_DONAU_KEYS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+#include "donau/donau_service.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Function to insert or update Donau keys in the merchant_donau_keys table.
+ *
+ * @param pg database context
+ * @param keys the DONAU_Keys object
+ * @param first_retry time when we make retry to update keys
+ * @return GNUNET_DB_QueryStatus transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_donau_keys (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const struct DONAU_Keys *keys,
+ struct GNUNET_TIME_Absolute first_retry);
+
+
+#endif
diff --git a/src/include/merchant-database/insert_inventory_lock.h b/src/include/merchant-database/insert_inventory_lock.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/insert_inventory_lock.h
+ * @brief implementation of the insert_inventory_lock function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_INSERT_INVENTORY_LOCK_H
+#define MERCHANT_DATABASE_INSERT_INVENTORY_LOCK_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Lock stocks of a particular product. Note that the transaction must
+ * enforce that the "stocked-sold-lost >= locked" constraint holds.
+ *
+ * @param pg database context
+ * @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 quantity_frac fractional component of quantity in units of
+ * 1/1000000 of the base value
+ * @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
+TALER_MERCHANTDB_insert_inventory_lock (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ const char *product_id,
+ const struct GNUNET_Uuid *uuid,
+ uint64_t quantity,
+ uint32_t quantity_frac,
+ struct GNUNET_TIME_Timestamp expiration_time);
+
+#endif
diff --git a/src/include/merchant-database/insert_mfa_challenge.h b/src/include/merchant-database/insert_mfa_challenge.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/insert_mfa_challenge.h
+ * @brief implementation of the insert_mfa_challenge function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_INSERT_MFA_CHALLENGE_H
+#define MERCHANT_DATABASE_INSERT_MFA_CHALLENGE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+/**
+ * Create new multi-factor authorization (MFA) challenge in the database.
+ *
+ * @param pg database context
+ * @param instance_name name of the instance impacted by the challenge;
+ * used when communicating with the user; instance does not yet
+ * need to exist (as it might be we are creating it!)
+ * @param op operation that triggered the MFA request
+ * @param h_body hash of the request body
+ * @param salt salt used to compute @a h_body
+ * @param code challenge code sent to the user
+ * @param expiration_date when should the challenge expire
+ * @param retransmission_date when do we next allow retransmission
+ * of the challenge
+ * @param tan_channel which channel was used
+ * @param required_address address
+ * where the challenge is to be sent
+ * @param[out] challenge_id set to the ID of the new challenge
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_insert_mfa_challenge (
+ struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_name,
+ enum TALER_MERCHANT_MFA_CriticalOperation op,
+ const struct TALER_MERCHANT_MFA_BodyHash *h_body,
+ const struct TALER_MERCHANT_MFA_BodySalt *salt,
+ const char *code,
+ struct GNUNET_TIME_Absolute expiration_date,
+ struct GNUNET_TIME_Absolute retransmission_date,
+ enum TALER_MERCHANT_MFA_Channel tan_channel,
+ const char *required_address,
+ uint64_t *challenge_id);
+
+#endif
diff --git a/src/include/merchant-database/insert_refund_by_coin.h b/src/include/merchant-database/insert_refund_by_coin.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/insert_refund_by_coin.h
+ * @brief implementation of the insert_refund_by_coin function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_INSERT_REFUND_BY_COIN_H
+#define MERCHANT_DATABASE_INSERT_REFUND_BY_COIN_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Function called during aborts to refund a coin. Marks the
+ * respective coin as refunded.
+ *
+ * @param pg database context
+ * @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 the refund
+ * @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
+TALER_MERCHANTDB_insert_refund_by_coin (struct TALER_MERCHANTDB_PostgresContext *pg,
+ 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);
+
+#endif
diff --git a/src/include/merchant-database/insert_wire_fee.h b/src/include/merchant-database/insert_wire_fee.h
@@ -0,0 +1,52 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/insert_wire_fee.h
+ * @brief implementation of the postgres_store_wire_fee_by_exchange function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_INSERT_WIRE_FEE_H
+#define MERCHANT_DATABASE_INSERT_WIRE_FEE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Store information about wire fees charged by an exchange,
+ * including signature (so we have proof).
+ *
+ * @param pg database context
+ * @param master_pub public key of the exchange
+ * @param h_wire_method hash of wire method
+ * @param fees the fee 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
+TALER_MERCHANTDB_insert_wire_fee (struct TALER_MERCHANTDB_PostgresContext *pg,
+ 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);
+
+#endif
diff --git a/src/include/merchant-database/lock_product.h b/src/include/merchant-database/lock_product.h
@@ -1,54 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/lock_product.h
- * @brief implementation of the lock_product function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_LOCK_PRODUCT_H
-#define MERCHANT_DATABASE_LOCK_PRODUCT_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Lock stocks of a particular product. Note that the transaction must
- * enforce that the "stocked-sold-lost >= locked" constraint holds.
- *
- * @param pg database context
- * @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 quantity_frac fractional component of quantity in units of
- * 1/1000000 of the base value
- * @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
-TALER_MERCHANTDB_lock_product (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- const char *product_id,
- const struct GNUNET_Uuid *uuid,
- uint64_t quantity,
- uint32_t quantity_frac,
- struct GNUNET_TIME_Timestamp expiration_time);
-
-#endif
diff --git a/src/include/merchant-database/mark_contract_paid.h b/src/include/merchant-database/mark_contract_paid.h
@@ -1,50 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/mark_contract_paid.h
- * @brief implementation of the mark_contract_paid function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_MARK_CONTRACT_PAID_H
-#define MERCHANT_DATABASE_MARK_CONTRACT_PAID_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * 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 pg database context
- * @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
- * @param choice_index the contract v1 choice index to select, -1 for v0
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_mark_contract_paid (struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *instance_id,
- const struct
- TALER_PrivateContractHashP *h_contract_terms,
- const char *session_id,
- int16_t choice_index);
-
-#endif
diff --git a/src/include/merchant-database/mark_order_wired.h b/src/include/merchant-database/mark_order_wired.h
@@ -1,41 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2023 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/mark_order_wired.h
- * @brief implementation of the mark_order_wired function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_MARK_ORDER_WIRED_H
-#define MERCHANT_DATABASE_MARK_ORDER_WIRED_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Set 'wired' status for an order to 'true'.
- *
- * @param pg database context
- * @param order_serial serial number of the order
- * @return transaction status
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_mark_order_wired (struct TALER_MERCHANTDB_PostgresContext *pg,
- uint64_t order_serial);
-
-#endif
diff --git a/src/include/merchant-database/purge_instance.h b/src/include/merchant-database/purge_instance.h
@@ -1,42 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/purge_instance.h
- * @brief implementation of the purge_instance function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_PURGE_INSTANCE_H
-#define MERCHANT_DATABASE_PURGE_INSTANCE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-/**
- * Purge an instance and all associated information from our database.
- * Highly likely to cause undesired data loss. Use with caution.
- *
- * @param pg database context
- * @param merchant_id identifier of the instance
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_purge_instance (
- struct TALER_MERCHANTDB_PostgresContext *pg,
- const char *merchant_id);
-
-#endif
diff --git a/src/include/merchant-database/refund_coin.h b/src/include/merchant-database/refund_coin.h
@@ -1,53 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/refund_coin.h
- * @brief implementation of the refund_coin function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_REFUND_COIN_H
-#define MERCHANT_DATABASE_REFUND_COIN_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Function called during aborts to refund a coin. Marks the
- * respective coin as refunded.
- *
- * @param pg database context
- * @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 the refund
- * @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
-TALER_MERCHANTDB_refund_coin (struct TALER_MERCHANTDB_PostgresContext *pg,
- 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);
-
-#endif
diff --git a/src/include/merchant-database/solve_mfa_challenge.h b/src/include/merchant-database/solve_mfa_challenge.h
@@ -1,54 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2025 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/solve_mfa_challenge.h
- * @brief implementation of the solve_mfa_challenge function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_SOLVE_MFA_CHALLENGE_H
-#define MERCHANT_DATABASE_SOLVE_MFA_CHALLENGE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Attempt to solve new multi-factor authorization (MFA) challenge.
- * Checks the solution against the code in the database and updates
- * the solution state and (on failure) retry counter depending on
- * the result.
- *
- * @param pg database context
- * @param challenge_id challenge ID to be solved
- * @param h_body body of the operation the challenge authorizes
- * @param solution proposed solution to be checked against the actual code
- * @param[out] solved set to true if the challenge was solved by
- * @a solution
- * @param[out] retry_counter set to the number of attempts that remain
- * for solving the challenge (after this time)
- * @return database result code
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_solve_mfa_challenge (struct TALER_MERCHANTDB_PostgresContext *pg,
- uint64_t challenge_id,
- const struct TALER_MERCHANT_MFA_BodyHash *h_body,
- const char *solution,
- bool *solved,
- uint32_t *retry_counter);
-
-#endif
diff --git a/src/include/merchant-database/store_wire_fee_by_exchange.h b/src/include/merchant-database/store_wire_fee_by_exchange.h
@@ -1,52 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/store_wire_fee_by_exchange.h
- * @brief implementation of the postgres_store_wire_fee_by_exchange function for Postgres
- * @author Christian Grothoff
- */
-#ifndef MERCHANT_DATABASE_STORE_WIRE_FEE_BY_EXCHANGE_H
-#define MERCHANT_DATABASE_STORE_WIRE_FEE_BY_EXCHANGE_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Store information about wire fees charged by an exchange,
- * including signature (so we have proof).
- *
- * @param pg database context
- * @param master_pub public key of the exchange
- * @param h_wire_method hash of wire method
- * @param fees the fee 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
-TALER_MERCHANTDB_store_wire_fee_by_exchange (struct TALER_MERCHANTDB_PostgresContext *pg,
- 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);
-
-#endif
diff --git a/src/include/merchant-database/unlock_inventory.h b/src/include/merchant-database/unlock_inventory.h
@@ -1,44 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/unlock_inventory.h
- * @brief implementation of the unlock_inventory function for Postgres
- * @author Iván Ávalos
- */
-#ifndef MERCHANT_DATABASE_UNLOCK_INVENTORY_H
-#define MERCHANT_DATABASE_UNLOCK_INVENTORY_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Release an inventory lock by UUID. Releases ALL stocks locked under
- * the given UUID.
- *
- * @param pg database context
- * @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
-TALER_MERCHANTDB_unlock_inventory (struct TALER_MERCHANTDB_PostgresContext *pg,
- const struct GNUNET_Uuid *uuid);
-
-#endif
diff --git a/src/include/merchant-database/update_money_pot_totals.h b/src/include/merchant-database/update_money_pot_totals.h
@@ -0,0 +1,50 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2025 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/update_money_pot_totals.h
+ * @brief implementation of the update_money_pot_totals function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_UPDATE_MONEY_POT_TOTALS_H
+#define MERCHANT_DATABASE_UPDATE_MONEY_POT_TOTALS_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Increment amounts in money pots. If a money pot does not exist,
+ * it is simply skipped (without causing an error!).
+ *
+ * @param pg database context
+ * @param instance_id instance to update money pot for
+ * @param money_pots_len length of the @a money_pots_ids
+ * and @a pot_increments arrays
+ * @param money_pot_ids serial numbers of the pots to increment
+ * @param pot_increments new amounts to add to the respective pot
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_money_pot_totals (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ size_t money_pots_len,
+ const uint64_t *money_pot_ids,
+ const struct TALER_Amount *pot_increments);
+
+
+#endif
diff --git a/src/include/merchant-database/update_to_account_inactive.h b/src/include/merchant-database/update_to_account_inactive.h
@@ -0,0 +1,44 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/update_to_account_inactive.h
+ * @brief implementation of the update_to_account_inactive function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_UPDATE_TO_ACCOUNT_INACTIVE_H
+#define MERCHANT_DATABASE_UPDATE_TO_ACCOUNT_INACTIVE_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Set an instance's account in our database to "inactive".
+ *
+ * @param pg database context
+ * @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
+TALER_MERCHANTDB_update_to_account_inactive (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *merchant_id,
+ const struct TALER_MerchantWireHashP *h_wire);
+
+
+#endif
diff --git a/src/include/merchant-database/update_to_contract_terms_paid.h b/src/include/merchant-database/update_to_contract_terms_paid.h
@@ -0,0 +1,50 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/update_to_contract_terms_paid.h
+ * @brief implementation of the update_to_contract_terms_paid function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_UPDATE_TO_CONTRACT_TERMS_PAID_H
+#define MERCHANT_DATABASE_UPDATE_TO_CONTRACT_TERMS_PAID_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * 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 pg database context
+ * @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
+ * @param choice_index the contract v1 choice index to select, -1 for v0
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_contract_terms_paid (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *instance_id,
+ const struct
+ TALER_PrivateContractHashP *h_contract_terms,
+ const char *session_id,
+ int16_t choice_index);
+
+#endif
diff --git a/src/include/merchant-database/update_to_contract_terms_wired.h b/src/include/merchant-database/update_to_contract_terms_wired.h
@@ -0,0 +1,41 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2023 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/update_to_contract_terms_wired.h
+ * @brief implementation of the update_to_contract_terms_wired function for Postgres
+ * @author Iván Ávalos
+ */
+#ifndef MERCHANT_DATABASE_UPDATE_TO_CONTRACT_TERMS_WIRED_H
+#define MERCHANT_DATABASE_UPDATE_TO_CONTRACT_TERMS_WIRED_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Set 'wired' status for an order to 'true'.
+ *
+ * @param pg database context
+ * @param order_serial serial number of the order
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_contract_terms_wired (struct TALER_MERCHANTDB_PostgresContext *pg,
+ uint64_t order_serial);
+
+#endif
diff --git a/src/include/merchant-database/update_to_instance_private_key_deleted.h b/src/include/merchant-database/update_to_instance_private_key_deleted.h
@@ -0,0 +1,42 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/update_to_instance_private_key_deleted.h
+ * @brief implementation of the update_to_instance_private_key_deleted function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_UPDATE_TO_INSTANCE_PRIVATE_KEY_DELETED_H
+#define MERCHANT_DATABASE_UPDATE_TO_INSTANCE_PRIVATE_KEY_DELETED_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Delete private key of an instance from our database.
+ *
+ * @param pg database context
+ * @param merchant_id identifier of the instance
+ * @return database result code
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_instance_private_key_deleted (struct TALER_MERCHANTDB_PostgresContext *pg
+ ,
+ const char *merchant_id);
+
+#endif
diff --git a/src/include/merchant-database/update_to_transfer_finalized.h b/src/include/merchant-database/update_to_transfer_finalized.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file src/include/merchant-database/update_to_transfer_finalized.h
+ * @brief implementation of the update_to_transfer_finalized function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef MERCHANT_DATABASE_UPDATE_TO_TRANSFER_FINALIZED_H
+#define MERCHANT_DATABASE_UPDATE_TO_TRANSFER_FINALIZED_H
+
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include "merchantdb_lib.h"
+
+
+struct TALER_MERCHANTDB_PostgresContext;
+/**
+ * Finalize transfer status.
+ *
+ * @param pg database context
+ * @param exchange_url the exchange that made the transfer
+ * @param wtid wire transfer subject
+ * @param h_details hash over all of the aggregated deposits
+ * @param total_amount total amount exchange claimed to have transferred
+ * @param wire_fee wire fee charged by the exchange
+ * @param exchange_pub key used to make @e exchange_sig
+ * @param exchange_sig signature of the exchange over reconciliation data
+ * @return database transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TALER_MERCHANTDB_update_to_transfer_finalized (struct TALER_MERCHANTDB_PostgresContext *pg,
+ const char *exchange_url,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct GNUNET_HashCode *h_details,
+ const struct TALER_Amount *total_amount,
+ const struct TALER_Amount *wire_fee,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig);
+
+
+#endif
diff --git a/src/include/merchant-database/upsert_donau_keys.h b/src/include/merchant-database/upsert_donau_keys.h
@@ -1,46 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2024 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU 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. If not, see <http://www.gnu.org/licenses/>
- */
-/**
- * @file src/include/merchant-database/upsert_donau_keys.h
- * @brief implementation of the upsert_donau_keys function for Postgres
- * @author Bohdan Potuzhnyi
- * @author Vlada Svirsh
- */
-#ifndef MERCHANT_DATABASE_UPSERT_DONAU_KEYS_H
-#define MERCHANT_DATABASE_UPSERT_DONAU_KEYS_H
-
-#include <taler/taler_util.h>
-#include <taler/taler_json_lib.h>
-#include "merchantdb_lib.h"
-#include "donau/donau_service.h"
-
-
-struct TALER_MERCHANTDB_PostgresContext;
-/**
- * Function to insert or update Donau keys in the merchant_donau_keys table.
- *
- * @param pg database context
- * @param keys the DONAU_Keys object
- * @param first_retry time when we make retry to update keys
- * @return GNUNET_DB_QueryStatus transaction status
- */
-enum GNUNET_DB_QueryStatus
-TALER_MERCHANTDB_upsert_donau_keys (struct TALER_MERCHANTDB_PostgresContext *pg,
- const struct DONAU_Keys *keys,
- struct GNUNET_TIME_Absolute first_retry);
-
-
-#endif