merchant

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

commit dc6dec302b54cf07dfe6aea32892d362d2beaab0
parent 8a0b9213289869830a18167fa60626b4d51468c0
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 25 Mar 2026 00:33:51 +0100

parse more of the product response in libtalermerchant

Diffstat:
Msrc/include/taler/taler-merchant/get-private-products-PRODUCT_ID.h | 30++++++++++++++++++++++++++++++
Msrc/lib/merchant_api_get-private-products-PRODUCT_ID.c | 69++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 94 insertions(+), 5 deletions(-)

diff --git a/src/include/taler/taler-merchant/get-private-products-PRODUCT_ID.h b/src/include/taler/taler-merchant/get-private-products-PRODUCT_ID.h @@ -140,6 +140,36 @@ struct TALER_MERCHANT_GetPrivateProductResponse */ struct GNUNET_TIME_Timestamp next_restock; + /** + * Number of categories in @a categories. + */ + unsigned int categories_len; + + /** + * Array of category IDs this product belongs to. + */ + const uint64_t *categories; + + /** + * Product group ID (0 if not set). + */ + uint64_t product_group_id; + + /** + * Money pot ID (0 if not set). + */ + uint64_t money_pot_id; + + /** + * Whether the price is net (excluding taxes). + */ + bool price_is_net; + + /** + * Minimum age required to purchase this product (0 if not set). + */ + uint16_t minimum_age; + } ok; } details; diff --git a/src/lib/merchant_api_get-private-products-PRODUCT_ID.c b/src/lib/merchant_api_get-private-products-PRODUCT_ID.c @@ -100,6 +100,7 @@ handle_get_product_finished (void *cls, { case MHD_HTTP_OK: { + const json_t *jcategories = NULL; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ( "product_name", @@ -158,23 +159,80 @@ handle_get_product_finished (void *cls, "next_restock", &pgr.details.ok.next_restock), NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_array_const ( + "categories", + &jcategories), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint64 ( + "product_group_id", + &pgr.details.ok.product_group_id), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint64 ( + "money_pot_id", + &pgr.details.ok.money_pot_id), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ( + "price_is_net", + &pgr.details.ok.price_is_net), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint16 ( + "minimum_age", + &pgr.details.ok.minimum_age), + NULL), GNUNET_JSON_spec_end () }; - if (GNUNET_OK == + if (GNUNET_OK != GNUNET_JSON_parse (json, spec, NULL, NULL)) { + pgr.hr.http_status = 0; + pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + } + { + unsigned int num_categories; + uint64_t *categories; + + num_categories = (unsigned int) json_array_size (jcategories); + if (json_array_size (jcategories) != (size_t) num_categories) + { + GNUNET_break (0); + pgr.hr.http_status = 0; + pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + } + categories = GNUNET_new_array (num_categories, + uint64_t); + for (unsigned int i = 0; i < num_categories; i++) + { + json_t *jval = json_array_get (jcategories, + i); + + if (! json_is_integer (jval)) + { + GNUNET_break_op (0); + GNUNET_free (categories); + pgr.hr.http_status = 0; + pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + goto done; + } + categories[i] = (uint64_t) json_integer_value (jval); + } + pgr.details.ok.categories_len = num_categories; + pgr.details.ok.categories = categories; gpp->cb (gpp->cb_cls, &pgr); - GNUNET_JSON_parse_free (spec); + GNUNET_free (categories); TALER_MERCHANT_get_private_product_cancel (gpp); return; } - pgr.hr.http_status = 0; - pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; } case MHD_HTTP_UNAUTHORIZED: pgr.hr.ec = TALER_JSON_get_error_code (json); @@ -193,6 +251,7 @@ handle_get_product_finished (void *cls, (int) pgr.hr.ec); break; } +done: gpp->cb (gpp->cb_cls, &pgr); TALER_MERCHANT_get_private_product_cancel (gpp);