commit 5cb9ea47557c18166a1f42768e495716c2f4594b
parent e28c2fc790a07dda17de2794ce2de8a5ee422529
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date: Mon, 23 Jun 2025 11:43:29 +0200
modifications on the taler_merchant_pay_service.c
Diffstat:
2 files changed, 140 insertions(+), 9 deletions(-)
diff --git a/src/backenddb/merchant-0019.sql b/src/backenddb/merchant-0019.sql
@@ -0,0 +1,88 @@
+--
+-- 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 merchant-0019.sql
+-- @brief Create table to store donau related information
+-- @author Bohdan Potuzhnyi
+-- @author Vlada Svirsh
+
+BEGIN;
+
+-- Check patch versioning is in place.
+SELECT _v.register_patch('merchant-0019', NULL, NULL);
+
+SET search_path TO merchant;
+
+CREATE TABLE IF NOT EXISTS merchant_donau_keys
+(donau_keys_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
+ ,donau_url TEXT PRIMARY KEY
+ ,keys_json TEXT NOT NULL
+);
+
+COMMENT ON TABLE merchant_donau_keys
+ IS 'Here we store the cached /keys response from Donau in JSON format';
+COMMENT ON COLUMN merchant_donau_keys.donau_keys_serial
+ IS 'Unique serial identifier for each cached key entry';
+COMMENT ON COLUMN merchant_donau_keys.donau_url
+ IS 'Base URL of Donau associated with these keys';
+COMMENT ON COLUMN merchant_donau_keys.keys_json
+ IS 'JSON string of the /keys as generated by Donau';
+
+CREATE TABLE IF NOT EXISTS merchant_donau_instances
+(donau_instances_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
+ ,donau_url TEXT NOT NULL
+ ,charity_name TEXT NOT NULL
+ ,charity_pub_key BYTEA CHECK (LENGTH(charity_pub_key)=32)
+ ,charity_id BIGINT NOT NULL
+ ,charity_max_per_year taler_amount_currency NOT NULL
+ ,charity_receipts_to_date taler_amount_currency NOT NULL
+ ,current_year INT8 NOT NULL
+);
+
+COMMENT ON TABLE merchant_donau_instances
+ IS 'Here we store information about individual Donau instances, including details about associated charities and donation limits';
+COMMENT ON COLUMN merchant_donau_instances.donau_instances_serial
+ IS 'Unique serial identifier for each Donau instance';
+COMMENT ON COLUMN merchant_donau_instances.donau_url
+ IS 'The URL associated with the Donau system for this instance';
+COMMENT ON COLUMN merchant_donau_instances.charity_pub_key
+ IS 'The public key of the charity organization linked to this instance, with a 32-byte length constraint';
+COMMENT ON COLUMN merchant_donau_instances.charity_id
+ IS 'The unique identifier for the charity organization linked to this Donau instance';
+COMMENT ON COLUMN merchant_donau_instances.charity_max_per_year
+ IS 'Maximum allowable donation amount per year for the charity associated with this instance, stored in taler_amount_currency';
+COMMENT ON COLUMN merchant_donau_instances.charity_receipts_to_date
+ IS 'The total amount of donations received to date for this instance, stored in taler_amount_currency';
+COMMENT ON COLUMN merchant_donau_instances.current_year
+ IS 'The current year for tracking donations for this instance, stored as an 8-byte integer';
+
+CREATE TABLE IF NOT EXISTS merchant_order_donau
+(order_donau_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
+ ,order_serial BIGINT NOT NULL
+ REFERENCES merchant_orders (order_serial) ON DELETE CASCADE
+ ,donau_budis TEXT NOT NULL
+);
+
+COMMENT ON TABLE merchant_order_donau
+ IS 'Table linking merchant orders with Donau BUDIS information';
+COMMENT ON COLUMN merchant_order_donau.order_donau_serial
+ IS 'Unique serial identifier for Donau order linkage';
+COMMENT ON COLUMN merchant_order_donau.order_serial
+ IS 'Foreign key linking to the corresponding merchant order';
+COMMENT ON COLUMN merchant_order_donau.donau_budis
+ IS 'Donau BUDIs json associated with the order';
+
+COMMIT;
+\ No newline at end of file
diff --git a/src/lib/taler_merchant_pay_service.c b/src/lib/taler_merchant_pay_service.c
@@ -91,7 +91,7 @@ struct TALER_MERCHANT_OrderPayHandle
const struct TALER_MERCHANT_OutputToken *output_tokens;
} output_tokens;
- /* computed once we see both choice_index and token_evs(outputs in the env): */
+ /* computed once we see both choice_index and tokens_evs(outputs in the env): */
json_t *wallet_data;
struct GNUNET_HashCode wallet_data_hash;
@@ -576,7 +576,7 @@ TALER_MERCHANT_order_pay_set_options (struct TALER_MERCHANT_OrderPayHandle *ph,
ph->output_tokens.output_tokens
= o->details.output_tokens.output_tokens;
{
- /* build and store token_evs */
+ /* build and store tokens_evs */
json_t *arr = json_array ();
for (unsigned j = 0; j < ph->output_tokens.num_output_tokens; j++) {
const struct TALER_MERCHANT_OutputToken *otk = &ph->output_tokens.output_tokens[j];
@@ -586,7 +586,7 @@ TALER_MERCHANT_order_pay_set_options (struct TALER_MERCHANT_OrderPayHandle *ph,
json_array_append_new (arr, je);
}
json_t *js = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_array_steal ("token_evs", arr)
+ GNUNET_JSON_pack_array_steal ("tokens_evs", arr)
);
store_json_option (ph, o->ot, js);
}
@@ -666,11 +666,11 @@ TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph)
/* --- build wallet_data hash for signing coins & tokens --- */
if (ph->has_choice_index) {
- /* wallet_data = { choice_index: …, token_evs: … } */
+ /* wallet_data = { choice_index: …, tokens_evs: … } */
ph->wallet_data = GNUNET_JSON_PACK (
GNUNET_JSON_pack_int64("choice_index", ph->choice_index),
GNUNET_JSON_pack_allow_null(
- GNUNET_JSON_pack_array_incref("token_evs", ph->body))
+ GNUNET_JSON_pack_array_incref("tokens_evs", ph->body))
);
TALER_json_hash (ph->wallet_data, &ph->wallet_data_hash);
}
@@ -740,7 +740,7 @@ TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph)
store_json_option (ph,
TALER_MERCHANT_OrderPayOptionType_COINS,
GNUNET_JSON_PACK (
- GNUNET_JSON_pack_array_steal ("paid_coins", arr)
+ GNUNET_JSON_pack_array_steal ("coins", arr)
)
);
}
@@ -772,12 +772,54 @@ TALER_MERCHANT_order_pay_start (struct TALER_MERCHANT_OrderPayHandle *ph)
store_json_option (ph,
TALER_MERCHANT_OrderPayOptionType_INPUT_TOKENS,
GNUNET_JSON_PACK (
- GNUNET_JSON_pack_array_steal ("used_tokens", arr)
+ GNUNET_JSON_pack_array_steal ("tokens", arr)
)
);
}
- //TODO: Change the usage of this function to how it is in the api_post_order_pay.c in the order_pay_frontend
- return fire_request (ph);
+ /* --- post the request --------------------------------------------------- */
+ {
+ /* BEGIN INLINE FIRE REQUEST (was fire_request()) */
+ char *path;
+ GNUNET_asprintf (&path,
+ "orders/%s/pay",
+ ph->order_id);
+ ph->url = TALER_url_join (ph->merchant_url,
+ path,
+ NULL);
+ GNUNET_free (path);
+
+ if (NULL == ph->url)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Could not construct request URL.\n");
+ json_decref (ph->body);
+ GNUNET_free (ph);
+ return TALER_MERCHANT_OPOEC_INVALID_VALUE;
+ }
+
+ CURL *eh = TALER_MERCHANT_curl_easy_get_ (ph->url);
+ if (GNUNET_OK !=
+ TALER_curl_easy_post (&ph->post_ctx,
+ eh,
+ ph->body))
+ {
+ GNUNET_break (0);
+ curl_easy_cleanup (eh);
+ json_decref (ph->body);
+ GNUNET_free (ph->url);
+ GNUNET_free (ph);
+ return TALER_MERCHANT_OPOEC_INVALID_VALUE;
+ }
+
+ json_decref (ph->body);
+ ph->job = GNUNET_CURL_job_add2 (ph->ctx,
+ eh,
+ ph->post_ctx.headers,
+ &handle_finished,
+ ph);
+ /* END INLINE FIRE REQUEST */
+ return TALER_MERCHANT_OPOEC_OK;
+ }
}