merchant

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

commit 73c070c5bbe418f95774d8eedf5b43cebe037fb6
parent 2459fbdd7fbb320ca4723447add0a00276041d3e
Author: Florian Dold <dold@taler.net>
Date:   Wed,  9 Sep 2026 15:57:49 +0200

merchantdb: wake KYC checker when status is requested

Send the KYC_UPDATE_FORCED notification when reading account KYC
status. The previous channel belonged to ACCOUNTS_CHANGED, whose
handler leaves existing inquiries on their periodic schedule. A
merchant could therefore keep reporting pending KYC after the exchange
had completed it, until the checker was restarted or its delay expired.

Issue: https://bugs.taler.net/n/11783

Diffstat:
Msrc/backenddb/iterate_kyc_statuses.sql | 2+-
Msrc/backenddb/test_merchantdb.c | 42++++++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/backenddb/iterate_kyc_statuses.sql b/src/backenddb/iterate_kyc_statuses.sql @@ -71,7 +71,7 @@ BEGIN UPDATE merchant_kyc SET next_kyc_poll=in_now WHERE kyc_serial_id = my_kyc_record.kyc_serial_id; - NOTIFY XDQM4Z4N0D3GX0H9JEXH70EBC2T3KY7HC0TJB0Z60D2H781RXR6AG; -- MERCHANT_EXCHANGE_KYC_UPDATE_FORCED + NOTIFY XJ40P0CFMZ0DT6SFZ70VRQ19KG1HP6AJ1Q6VCDZN4N2FGPSAG4KDG; -- MERCHANT_EXCHANGE_KYC_UPDATE_FORCED RETURN QUERY SELECT my_h_wire, diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c @@ -8370,10 +8370,16 @@ test_insert_kyc_failure ( .size = htons (sizeof (general_event)), .type = htons (TALER_DBEVENT_MERCHANT_KYC_STATUS_CHANGED) }; + struct GNUNET_DB_EventHeaderP refresh_event = { + .size = htons (sizeof (refresh_event)), + .type = htons (TALER_DBEVENT_MERCHANT_EXCHANGE_KYC_UPDATE_FORCED) + }; struct GNUNET_DB_EventHandler *account_eh = NULL; struct GNUNET_DB_EventHandler *general_eh = NULL; + struct GNUNET_DB_EventHandler *refresh_eh = NULL; unsigned int account_events = 0; unsigned int general_events = 0; + unsigned int refresh_events = 0; struct KycFailureExpected expected = { .account = account, .exchange_url = exchange_url, @@ -8409,6 +8415,17 @@ test_insert_kyc_failure ( "Failed to listen for general KYC events\n"); goto cleanup; } + refresh_eh = TALER_MERCHANTDB_event_listen ( + pg, + &refresh_event, + GNUNET_TIME_UNIT_FOREVER_REL, + &kyc_event_cb, + &refresh_events); + if (NULL == refresh_eh) + { + GNUNET_break (0); + goto cleanup; + } expected.timestamp = GNUNET_TIME_timestamp_get (); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != @@ -8458,6 +8475,19 @@ test_insert_kyc_failure ( "Inserted KYC failure did not match expectations\n"); goto cleanup; } + /* Reading the status must wake the KYC checker, including an inquiry + sleeping until its next periodic check. An ACCOUNTS_CHANGED event + reloads the account list but leaves existing inquiries asleep. */ + GNUNET_PQ_event_do_poll (pg->conn); + if (1 != refresh_events) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Reading KYC status generated %u forced refresh events," + " expected one\n", + refresh_events); + goto cleanup; + } expected.timestamp = GNUNET_TIME_timestamp_get (); expected.exchange_http_status = MHD_HTTP_ACCEPTED; @@ -8510,9 +8540,21 @@ test_insert_kyc_failure ( "Updated KYC failure did not match expectations\n"); goto cleanup; } + GNUNET_PQ_event_do_poll (pg->conn); + if (2 != refresh_events) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Reading updated KYC status generated %u forced refresh" + " events, expected two\n", + refresh_events); + goto cleanup; + } ret = 0; cleanup: + if (NULL != refresh_eh) + TALER_MERCHANTDB_event_listen_cancel (refresh_eh); if (NULL != general_eh) TALER_MERCHANTDB_event_listen_cancel (general_eh); if (NULL != account_eh)