merchant

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

commit 812df5ba2672e0d9d5b06c47d05bf0636274586f
parent 26094832ff4cc20c3aab7242e1ee25b1291da256
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu,  5 Feb 2026 20:42:45 +0100

new DB routines for #10965/#9961

Diffstat:
Msrc/backend/taler-merchant-httpd_dispatcher.c | 16+++++++++++++---
Msrc/backend/taler-merchant-httpd_private-get-incoming.c | 2+-
Msrc/backenddb/Makefile.am | 3+++
Msrc/backenddb/merchant-0030.sql | 4++--
Asrc/backenddb/pg_insert_unclaim_signature.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_insert_unclaim_signature.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_insert_unclaim_signature.sql | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_lookup_expected_transfer.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_lookup_expected_transfer.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_lookup_reconciliation_details.c | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_lookup_reconciliation_details.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/backenddb/pg_template.c | 2+-
Msrc/backenddb/plugin_merchantdb_postgres.c | 9+++++++++
Msrc/include/taler_merchantdb_plugin.h | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14 files changed, 673 insertions(+), 7 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_dispatcher.c b/src/backend/taler-merchant-httpd_dispatcher.c @@ -46,6 +46,7 @@ #include "taler-merchant-httpd_private-get-units.h" #include "taler-merchant-httpd_private-get-units-ID.h" #include "taler-merchant-httpd_private-get-incoming.h" +#include "taler-merchant-httpd_private-get-incoming-ID.h" #include "taler-merchant-httpd_private-get-instances.h" #include "taler-merchant-httpd_private-get-instances-ID.h" #include "taler-merchant-httpd_private-get-instances-ID-kyc.h" @@ -613,6 +614,15 @@ determine_handler_group (const char **urlp, .allow_deleted_instance = true, .handler = &TMH_private_get_incoming }, + /* GET /incoming/$ID: */ + { + .url_prefix = "/incoming", + .permission = "transfers-read", + .method = MHD_HTTP_METHOD_GET, + .allow_deleted_instance = true, + .have_id_segment = true, + .handler = &TMH_private_get_incoming_ID + }, /* POST /otp-devices: */ { .url_prefix = "/otp-devices", @@ -627,7 +637,7 @@ determine_handler_group (const char **urlp, .method = MHD_HTTP_METHOD_GET, .handler = &TMH_private_get_otp_devices }, - /* GET /otp-devices/$ID/: */ + /* GET /otp-devices/$ID: */ { .url_prefix = "/otp-devices/", .method = MHD_HTTP_METHOD_GET, @@ -635,7 +645,7 @@ determine_handler_group (const char **urlp, .have_id_segment = true, .handler = &TMH_private_get_otp_devices_ID }, - /* DELETE /otp-devices/$ID/: */ + /* DELETE /otp-devices/$ID: */ { .url_prefix = "/otp-devices/", .method = MHD_HTTP_METHOD_DELETE, @@ -643,7 +653,7 @@ determine_handler_group (const char **urlp, .have_id_segment = true, .handler = &TMH_private_delete_otp_devices_ID }, - /* PATCH /otp-devices/$ID/: */ + /* PATCH /otp-devices/$ID: */ { .url_prefix = "/otp-devices/", .method = MHD_HTTP_METHOD_PATCH, diff --git a/src/backend/taler-merchant-httpd_private-get-incoming.c b/src/backend/taler-merchant-httpd_private-get-incoming.c @@ -180,7 +180,7 @@ TMH_private_get_incoming (const struct TMH_RequestHandler *rh, return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, - "incoming"); + "lookup_expected_transfers"); } return TALER_MHD_REPLY_JSON_PACK ( connection, diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am @@ -164,6 +164,9 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \ pg_delete_product_group.h pg_delete_product_group.c \ pg_update_product_group.h pg_update_product_group.c \ pg_select_product_groups.h pg_select_product_groups.c \ + pg_insert_unclaim_signature.h pg_insert_unclaim_signature.c \ + pg_lookup_reconciliation_details.h pg_lookup_reconciliation_details.c \ + pg_lookup_expected_transfer.h pg_lookup_expected_transfer.c \ pg_insert_money_pot.h pg_insert_money_pot.c \ pg_delete_money_pot.h pg_delete_money_pot.c \ pg_update_money_pot.h pg_update_money_pot.c \ diff --git a/src/backenddb/merchant-0030.sql b/src/backenddb/merchant-0030.sql @@ -26,8 +26,8 @@ SET search_path TO merchant; CREATE TABLE IF NOT EXISTS merchant_unclaim_signatures (unclaim_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE - ,h_contract_terms BYTEA PRIMARY KEY CHECK (LENGTH(h_contract_terms)=64) - ,unclaim_sig BYTEA NOT NULL CHECK (LENGTH(unclaim_sig)=64) + ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) + ,unclaim_sig BYTEA PRIMARY KEY CHECK (LENGTH(unclaim_sig)=64) ,expiration_time INT8 NOT NULL ); diff --git a/src/backenddb/pg_insert_unclaim_signature.c b/src/backenddb/pg_insert_unclaim_signature.c @@ -0,0 +1,100 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 backenddb/pg_insert_unclaim_signature.c + * @brief Implementation of the insert_unclaim_signature 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 "pg_insert_unclaim_signature.h" +#include "pg_helper.h" + + +static char * +get_notify_str (const char *order_id, + const struct TALER_MerchantPublicKeyP *merchant_pub) +{ + struct TMH_OrderPayEventP pay_eh = { + .header.size = htons (sizeof (pay_eh)), + .header.type = htons (TALER_DBEVENT_MERCHANT_ORDER_STATUS_CHANGED), + .merchant_pub = *merchant_pub + }; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Notifying clients about status change of order %s\n", + order_id); + GNUNET_CRYPTO_hash (order_id, + strlen (order_id), + &pay_eh.h_order_id); + return GNUNET_PQ_get_event_notify_channel (&pay_eh.header); +} + + +enum GNUNET_DB_QueryStatus +TMH_PG_insert_unclaim_signature ( + void *cls, + const char *instance_id, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *order_id, + const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, + const struct GNUNET_HashCode *h_contract, + const struct GNUNET_CRYPTO_EddsaSignature *nsig) +{ + struct PostgresClosure *pg = cls; + char *nonce_str = GNUNET_STRINGS_data_to_string_alloc (nonce, + sizeof (*nonce)); + char *notify_str = get_notify_str (order_id, + merchant_pub); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_string (order_id), + GNUNET_PQ_query_param_string (nonce_str), + GNUNET_PQ_query_param_string (notify_str), + GNUNET_PQ_query_param_auto_from_type (h_contract), + GNUNET_PQ_query_param_auto_from_type (nsig), + GNUNET_PQ_query_param_end + }; + bool found; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_bool ("out_found", + &found), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + check_connection (pg); + PREPARE (pg, + "insert_unclaim_signature", + "SELECT" + " out_found" + " FROM merchant_do_insert_unclaim_signature" + "($1, $2, $3, $4, $5);"); + qs = GNUNET_PQ_eval_prepared_singleton_select ( + pg->conn, + "insert_unclaim_signature", + params, + rs); + GNUNET_free (nonce_str); + GNUNET_free (notify_str); + if (qs <= 0) + return qs; + return found + ? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT + : GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; +} diff --git a/src/backenddb/pg_insert_unclaim_signature.h b/src/backenddb/pg_insert_unclaim_signature.h @@ -0,0 +1,51 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 backenddb/pg_insert_unclaim_signature.h + * @brief implementation of the insert_unclaim_signature function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_INSERT_UNCLAIM_SIGNATURE_H +#define PG_INSERT_UNCLAIM_SIGNATURE_H + +#include <taler/taler_util.h> +#include <taler/taler_json_lib.h> +#include "taler_merchantdb_plugin.h" + +/** + * Insert unclaim signature into DB and unclaim the order. + * + * @param cls closure + * @param instance_id instance of the operation (checked) + * @param merchant_pub public key of the instance (for notifications) + * @param order_id identifies the order to unclaim + * @param nonce claim nonce of the original claim + * @param h_contract hash of the contract to unclaim + * @param nsig signature by the nonce private key authorizing the unclaim + * @return transaction status, 0 if an order with this @a nonce + * and @a h_contract was not found; 1 if the request is idempotent + */ +enum GNUNET_DB_QueryStatus +TMH_PG_insert_unclaim_signature ( + void *cls, + const char *instance_id, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *order_id, + const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, + const struct GNUNET_HashCode *h_contract, + const struct GNUNET_CRYPTO_EddsaSignature *nsig); + +#endif diff --git a/src/backenddb/pg_insert_unclaim_signature.sql b/src/backenddb/pg_insert_unclaim_signature.sql @@ -0,0 +1,85 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2026 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/> +-- + + +DROP FUNCTION IF EXISTS merchant_do_insert_unclaim_signature; +CREATE FUNCTION merchant_do_insert_unclaim_signature ( + IN in_instance_id TEXT, + IN in_order_id TEXT, + IN in_nonce_str TEXT, + IN in_notify_str TEXT, + IN in_h_contract_terms BYTEA, + IN in_nonce_sig BYTEA, + OUT out_found BOOL) +LANGUAGE plpgsql +AS $$ +DECLARE + my_merchant_serial INT8; + my_expiration_time INT8; +BEGIN + + SELECT merchant_serial + INTO my_merchant_serial + FROM merchant_instances + WHERE merchant_id=in_instance_id; + + IF NOT FOUND + THEN + out_found = FALSE; + RETURN; + END IF; + + SELECT pay_deadline + INTO my_expiration_time + FROM merchant_contract_terms + WHERE order_id=in_order_id + AND merchant_serial = my_merchant_serial + AND contract_terms->>'nonce' = in_nonce_str; + + IF NOT FOUND + THEN + out_found = FALSE; + RETURN; + END IF; + + INSERT INTO merchant_unclaim_signatures + (h_contract_terms + ,unclaim_sig + ,expiration_time) + VALUES + (in_h_contract_terms + ,in_nonce_sig + ,my_expiration_time) + ON CONFLICT DO NOTHING: + + IF FOUND + THEN + out_found = TRUE; + + -- order status change notification + EXECUTE FORMAT ( + 'NOTIFY %s' + ,in_notify_str); + + RETURN; + END IF; + + PERFORM FROM merchant_unclaim_signatures + WHERE h_contract_terms = in_h_contract_terms + AND unclaim_sig = in_nonce_sig; + out_found = FOUND; + +END $$; diff --git a/src/backenddb/pg_lookup_expected_transfer.c b/src/backenddb/pg_lookup_expected_transfer.c @@ -0,0 +1,74 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 backenddb/pg_lookup_expected_transfer.c + * @brief Implementation of the lookup_expected_transfer 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 "pg_lookup_expected_transfer.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_expected_transfer ( + void *cls, + const char *instance_id, + uint64_t expected_incoming_serial, + struct GNUNET_TIME_Timestamp *execution_date, + char **payto_uri, + struct TALER_MasterPublicKeyP *master_pub) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_uint64 (&expected_incoming_serial), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("expected_time", + execution_date), + GNUNET_PQ_result_spec_string ("payto_uri", + payto_uri), + GNUNET_PQ_result_spec_auto_from_type ("master_pub", + master_pub), + GNUNET_PQ_result_spec_end + }; + + check_connection (pg); + PREPARE (pg, + "lookup_expected_transfer", + "SELECT" + " met.expected_time" + " ,ma.payto_uri" + " ,esk.master_pub" + " FROM merchant_expected_transfers met" + " JOIN merchant_exchange_signing_keys esk" + " USING (signkey_serial)" + " JOIN merchant_accounts ma" + " USING (account_serial)" + " JOIN merchant_instances inst" + " USING (merchant_serial)" + " WHERE inst.merchant_id=$1" + " AND met.expected_credit_serial=$2"); + return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "lookup_expected_transfer", + params, + rs); +} diff --git a/src/backenddb/pg_lookup_expected_transfer.h b/src/backenddb/pg_lookup_expected_transfer.h @@ -0,0 +1,49 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 backenddb/pg_lookup_expected_transfer.h + * @brief implementation of the lookup_expected_transfer function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_LOOKUP_EXPECTED_TRANSFER_H +#define PG_LOOKUP_EXPECTED_TRANSFER_H + +#include <taler/taler_util.h> +#include <taler/taler_json_lib.h> +#include "taler_merchantdb_plugin.h" + +/** + * Obtain information about an expected incoming wire transfer. + * + * @param cls closure + * @param instance_id instance to lookup payments for + * @param expected_incoming_serial serial number of the transfer + * @param[out] execution_date date of the transfer + * @param[out] payto_uri target bank account + * @param[out] master_pub master public key of the exchange + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_expected_transfer ( + void *cls, + const char *instance_id, + uint64_t expected_incoming_serial, + struct GNUNET_TIME_Timestamp *execution_date, + char **payto_uri, + struct TALER_MasterPublicKeyP *master_pub); + + +#endif diff --git a/src/backenddb/pg_lookup_reconciliation_details.c b/src/backenddb/pg_lookup_reconciliation_details.c @@ -0,0 +1,154 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 backenddb/pg_lookup_reconciliation_details.c + * @brief Implementation of the lookup_reconciliation_details 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 "pg_lookup_reconciliation_details.h" +#include "pg_helper.h" + + +/** + * Context for TMH_PG_lookup_reconciliation_details(). + */ +struct ReconciliationContext +{ + /** + * Function to call with the results. + */ + TALER_MERCHANTDB_ReconciliationDetailsCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Database context. + */ + struct PostgresClosure *pg; + + /** + * Set to the return value on errors. + */ + enum GNUNET_DB_QueryStatus qs; + +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results about reconciliation + * details. + * + * @param cls of type `struct ReconciliationContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +reconciliation_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct ReconciliationContext *lic = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *order_id; + struct TALER_Amount remaining_deposit; + struct TALER_Amount deposit_fee; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("order_id", + &order_id), + TALER_PQ_result_spec_amount_with_currency ("exchange_deposit_value", + &remaining_deposit), + TALER_PQ_result_spec_amount_with_currency ("exchange_deposit_fee", + &deposit_fee), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + lic->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + + lic->cb (lic->cb_cls, + order_id, + &remaining_deposit, + &deposit_fee); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_reconciliation_details ( + void *cls, + const char *instance_id, + uint64_t expected_incoming_serial, + TALER_MERCHANTDB_ReconciliationDetailsCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct ReconciliationContext lic = { + .cb = cb, + .cb_cls = cb_cls, + .pg = pg + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (instance_id), + GNUNET_PQ_query_param_uint64 (&expected_incoming_serial), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + check_connection (pg); + PREPARE (pg, + "lookup_reconciliation_details", + "SELECT" + " mct.order_id" + ",etc.exchange_deposit_value" + ",etc.exchange_deposit_fee" + " FROM merchant_expected_transfer_to_coin etc" + " JOIN merchant_deposits md" + " USING (deposit_serial)" + " JOIN merchant_deposit_confirmations mdc" + " USING (deposit_confirmation_serial)" + " JOIN merchant_contract_terms mct" + " USING (order_serial)" + " JOIN merchant_instances mi" + " USING (merchant_serial)" + " WHERE expected_credit_serial=$2" + " AND mi.merchant_id=$1;"); + qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, + "lookup_reconciliation_details", + params, + &reconciliation_cb, + &lic); + if (0 > lic.qs) + return lic.qs; + return qs; +} diff --git a/src/backenddb/pg_lookup_reconciliation_details.h b/src/backenddb/pg_lookup_reconciliation_details.h @@ -0,0 +1,48 @@ +/* + This file is part of TALER + Copyright (C) 2026 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 backenddb/pg_lookup_reconciliation_details.h + * @brief implementation of the lookup_reconciliation_details function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_LOOKUP_RECONCILIATION_DETAILS_H +#define PG_LOOKUP_RECONCILIATION_DETAILS_H + +#include <taler/taler_util.h> +#include <taler/taler_json_lib.h> +#include "taler_merchantdb_plugin.h" + + +/** + * Obtain reconciliation details for an expected incoming wire transfer. + * + * @param cls closure + * @param instance_id instance to lookup payments for + * @param expected_incoming_serial serial number of the transfer + * @param cb callback to invoke + * @param cb_cls closure for @a cb + * @return transaction status code + */ +enum GNUNET_DB_QueryStatus +TMH_PG_lookup_reconciliation_details ( + void *cls, + const char *instance_id, + uint64_t expected_incoming_serial, + TALER_MERCHANTDB_ReconciliationDetailsCallback cb, + void *cb_cls); + + +#endif diff --git a/src/backenddb/pg_template.c b/src/backenddb/pg_template.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2026 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 diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c @@ -51,6 +51,9 @@ #include "pg_lookup_transfers.h" #include "pg_lookup_pending_deposits.h" #include "pg_lookup_categories.h" +#include "pg_insert_unclaim_signature.h" +#include "pg_lookup_reconciliation_details.h" +#include "pg_lookup_expected_transfer.h" #include "pg_lookup_categories_by_ids.h" #include "pg_lookup_units.h" #include "pg_lookup_custom_units_by_names.h" @@ -518,6 +521,12 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) = &TMH_PG_select_otp; plugin->select_otp_serial = &TMH_PG_select_otp_serial; + plugin->insert_unclaim_signature + = &TMH_PG_insert_unclaim_signature; + plugin->lookup_reconciliation_details + = &TMH_PG_lookup_reconciliation_details; + plugin->lookup_expected_transfer + = &TMH_PG_lookup_expected_transfer; plugin->lock_product = &TMH_PG_lock_product; plugin->expire_locks diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h @@ -1822,6 +1822,25 @@ typedef void const char *bucket_range, uint64_t cumulative_counter); + +/** + * Function returning reconciliation details for an + * expected incoming wire transfer. + * Called by `lookup_reconciliation_details`. + * + * @param cls closure + * @param order_id order that was paid and then aggregated + * @param remaining_deposit deposited amount minus any refunds + * @param deposit_fee deposit fees paid to the exchange for the order + */ +typedef void +(*TALER_MERCHANTDB_ReconciliationDetailsCallback)( + void *cls, + const char *order_id, + const struct TALER_Amount *remaining_deposit, + const struct TALER_Amount *deposit_fee); + + /** * Details about a statistic with counter. */ @@ -2901,6 +2920,30 @@ struct TALER_MERCHANTDB_Plugin /** + * Insert unclaim signature into DB and unclaim the order. + * + * @param cls closure + * @param instance_id instance of the operation (checked) + * @param merchant_pub public key of the instance (for notifications) + * @param order_id identifies the order to unclaim + * @param nonce claim nonce of the original claim + * @param h_contract hash of the contract to unclaim + * @param nsig signature by the nonce private key authorizing the unclaim + * @return transaction status, 0 if an order with this @a nonce + * and @a h_contract was not found; 1 if the request is idempotent + */ + enum GNUNET_DB_QueryStatus + (*insert_unclaim_signature)( + void *cls, + const char *instance_id, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const char *order_id, + const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, + const struct GNUNET_HashCode *h_contract, + const struct GNUNET_CRYPTO_EddsaSignature *nsig); + + + /** * Insert blinded signatures for an order. * * @param cls closure @@ -3792,6 +3835,46 @@ struct TALER_MERCHANTDB_Plugin /** + * Obtain information about an expected incoming wire transfer. + * + * @param cls closure + * @param instance_id instance to lookup payments for + * @param expected_incoming_serial serial number of the transfer + * @param[out] execution_date date of the transfer + * @param[out] payto_uri target bank account + * @param[out] master_pub master public key of the exchange + * @return transaction status code + */ + enum GNUNET_DB_QueryStatus + (*lookup_expected_transfer)( + void *cls, + const char *instance_id, + uint64_t expected_incoming_serial, + struct GNUNET_TIME_Timestamp *execution_date, + char **payto_uri, + struct TALER_MasterPublicKeyP *master_pub); + + + /** + * Obtain reconciliation details for an expected incoming wire transfer. + * + * @param cls closure + * @param instance_id instance to lookup payments for + * @param expected_incoming_serial serial number of the transfer + * @param cb callback to invoke + * @param cb_cls closure for @a cb + * @return transaction status code + */ + enum GNUNET_DB_QueryStatus + (*lookup_reconciliation_details)( + void *cls, + const char *instance_id, + uint64_t expected_incoming_serial, + TALER_MERCHANTDB_ReconciliationDetailsCallback cb, + void *cb_cls); + + + /** * Lookup information about coin payments by @a h_contract_terms and * @a coin_pub. *