merchant

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

commit 7dbf4d319487cc38e65eea1c8dc9c21d4dec47f6
parent d9da83c7896ea682afdf6b5f01eeac12146f4792
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Fri, 14 Aug 2026 23:30:01 +0200

check tip currency matches

Diffstat:
Msrc/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c | 27++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c b/src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c @@ -1807,10 +1807,16 @@ handle_phase_compute_price (struct UseContext *uc) GNUNET_assert (0); } primary_currency = uc->template_contract.currency; - if (! uc->parse_request.no_amount) - primary_currency = uc->parse_request.amount.currency; if (! uc->parse_request.no_tip) primary_currency = uc->parse_request.tip.currency; + /* An 'amount' given by the client takes precedence over the currency + of the 'tip': the total we compute here is later compared against + that 'amount' in #handle_phase_check_total(), which requires both + to be in the same currency. If the tip then uses a different + currency, #handle_phase_check_tip() rejects the request with a + proper error instead. */ + if (! uc->parse_request.no_amount) + primary_currency = uc->parse_request.amount.currency; if (NULL == primary_currency) { ret = compute_totals_per_currency (uc); @@ -1944,9 +1950,20 @@ handle_phase_check_total (struct UseContext *uc) if (! uc->parse_request.no_amount) { GNUNET_assert (1 == uc->compute_price.totals_len); - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency (&uc->parse_request.amount, - &uc->compute_price.totals[0])); + if (GNUNET_YES != + TALER_amount_cmp_currency (&uc->parse_request.amount, + &uc->compute_price.totals[0])) + { + /* Must not be an assertion: the currency of the total we computed + is influenced by the client (via 'tip' and the selected + products), so a mismatch here is remotely triggerable. */ + GNUNET_break_op (0); + use_reply_with_error (uc, + MHD_HTTP_CONFLICT, + TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH, + uc->compute_price.totals[0].currency); + return; + } if (0 != TALER_amount_cmp (&uc->parse_request.amount, &uc->compute_price.totals[0]))