merchant

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

commit 45f620dc26c76ccd62f1985b1ed24eaf5fceb987
parent 2969d5cd6e26f3a49e72d14da50590d6ad44e05c
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 20 Apr 2026 15:09:09 +0200

add max_pickup_duration/time support

Diffstat:
Msrc/backend/taler-merchant-httpd_exchanges.c | 1-
Msrc/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c | 13+++++++++++++
Msrc/include/taler/taler_merchant_util.h | 13+++++++++++++
Msrc/util/contract_parse.c | 5+++++
Msrc/util/contract_serialize.c | 6++++++
Msrc/util/template_parse.c | 6+++++-
Auncrustify.cfg | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 137 insertions(+), 2 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_exchanges.c b/src/backend/taler-merchant-httpd_exchanges.c @@ -24,7 +24,6 @@ #include <taler/taler_dbevents.h> #include "taler-merchant-httpd_exchanges.h" #include "taler-merchant-httpd.h" -#include <regex.h> #include "merchant-database/get_kyc_limits.h" #include "merchant-database/select_exchange_keys.h" #include "merchant-database/event_listen.h" diff --git a/src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c b/src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c @@ -1631,6 +1631,19 @@ create_using_templates_inventory (struct UseContext *uc) NULL == uc->parse_request.summary ? uc->template_contract.summary : uc->parse_request.summary)))); + if (! GNUNET_TIME_relative_is_forever ( + uc->template_contract.max_pickup_duration)) + { + GNUNET_assert ( + 0 == + json_object_set_new ( + uc->ihc.request_body, + "max_pickup_time", + GNUNET_JSON_from_timestamp ( + GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_relative_to_absolute ( + uc->template_contract.max_pickup_duration))))); + } } diff --git a/src/include/taler/taler_merchant_util.h b/src/include/taler/taler_merchant_util.h @@ -368,6 +368,12 @@ struct TALER_MERCHANT_TemplateContract */ struct GNUNET_TIME_Relative pay_duration; + /** + * How long does the user have at most to access/pickup the (digital) + * goods or service they bought. Optional, defaults to FOREVER. + */ + struct GNUNET_TIME_Relative max_pickup_duration; + union { @@ -1192,6 +1198,13 @@ struct TALER_MERCHANT_Contract struct GNUNET_TIME_Timestamp delivery_date; /** + * Latest time until which the good or service may be + * picked up by the customer. This is usually for digital + * goods where the customer has a finite window for downloading. + */ + struct GNUNET_TIME_Timestamp max_pickup_time; + + /** * Merchant public key. */ struct TALER_MerchantPublicKeyP merchant_pub; diff --git a/src/util/contract_parse.c b/src/util/contract_parse.c @@ -1490,6 +1490,10 @@ TALER_MERCHANT_contract_parse (json_t *input, GNUNET_JSON_spec_timestamp ("delivery_date", &contract->delivery_date), NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_timestamp ("max_pickup_time", + &contract->max_pickup_time), + NULL), (nonce_optional) ? GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string_copy ("nonce", @@ -1521,6 +1525,7 @@ TALER_MERCHANT_contract_parse (json_t *input, unsigned int eline; GNUNET_assert (NULL != input); + contract->max_pickup_time = GNUNET_TIME_UNIT_FOREVER_TS; res = GNUNET_JSON_parse (input, espec, &ename, diff --git a/src/util/contract_serialize.c b/src/util/contract_serialize.c @@ -569,6 +569,12 @@ success: GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_timestamp ("delivery_date", input->delivery_date)), + GNUNET_JSON_pack_allow_null ( + GNUNET_TIME_absolute_is_never (input->max_pickup_time.abs_time) + ? GNUNET_JSON_pack_string ("dummy", + NULL) + : GNUNET_JSON_pack_timestamp ("max_pickup_time", + input->max_pickup_time)), (nonce_optional) ? GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("nonce", diff --git a/src/util/template_parse.c b/src/util/template_parse.c @@ -268,6 +268,10 @@ TALER_MERCHANT_template_contract_parse ( &out->pay_duration), NULL), GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_relative_time ("max_pickup_duration", + &out->max_pickup_duration), + NULL), + GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_bool ("request_tip", &out->request_tip), NULL), @@ -281,7 +285,7 @@ TALER_MERCHANT_template_contract_parse ( *error_name = "template_contract is NULL"; return GNUNET_SYSERR; } - + out->max_pickup_duration = GNUNET_TIME_UNIT_FOREVER_REL; if (GNUNET_OK != GNUNET_JSON_parse ((json_t *) template_contract, spec, diff --git a/uncrustify.cfg b/uncrustify.cfg @@ -0,0 +1,95 @@ +input_tab_size = 2 +output_tab_size = 2 + +indent_columns = 2 +indent_with_tabs = 0 +indent_case_brace = 2 +indent_label=-16 + +code_width=100 +#cmd_width=80 + +# Leave most comments alone for now +cmt_indent_multi=false +sp_cmt_cpp_start=add + +sp_not=add + +sp_func_call_user_paren_paren=remove +sp_inside_fparen=remove +sp_after_cast=add + +ls_for_split_full=true +ls_func_split_full=true +ls_code_width=true + +# Arithmetic operations in wrapped expressions should be at the start +# of the line. +pos_arith=lead + +# Fully parenthesize boolean exprs +mod_full_paren_if_bool=false + +# Braces should be on their own line +nl_fdef_brace=add +nl_enum_brace=add +nl_struct_brace=add +nl_union_brace=add +nl_if_brace=add +nl_brace_else=add +nl_elseif_brace=add +nl_while_brace=add +nl_switch_brace=add + +# no newline between "else" and "if" +nl_else_if=remove + +nl_func_paren=remove +nl_assign_brace=remove + +# No extra newlines that cause noisy diffs +nl_start_of_file=remove +nl_after_func_proto = 2 +nl_after_func_body = 3 +# If there's no new line, it's not a text file! +nl_end_of_file=add +nl_max_blank_in_func = 3 +nl_max = 3 + +sp_inside_paren = remove + +sp_arith = add +sp_arith_additive = add + +# We want spaces before and after "=" +sp_before_assign = add +sp_after_assign = add + +# we want "char *foo;" +sp_after_ptr_star = remove +sp_between_ptr_star = remove + +# we want "if (foo) { ... }" +sp_before_sparen = add + +sp_inside_fparen = remove +sp_inside_sparen = remove + +# add space before function call and decl: "foo (x)" +sp_func_call_paren = add +sp_func_proto_paren = add +sp_func_proto_paren_empty = add +sp_func_def_paren = add +sp_func_def_paren_empty = add + +# We'd want it for "if ( (foo) || (bar) )", but not for "if (m())", +# so as uncrustify doesn't give exactly what we want => ignore +sp_paren_paren = ignore +sp_inside_paren = remove +sp_bool = force + +nl_func_type_name = force +#nl_branch_else = add +nl_else_brace = add +nl_elseif_brace = add +nl_for_brace = add