merchant

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

commit cdd9de84bcc57bab62ab23fbef2929484afd16c9
parent fc9d1dcffd6a48fa54ac6baba1d0a2b9acd9f3f3
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue,  4 Aug 2026 18:50:14 +0200

be more strict when parsing slugs

Diffstat:
Msrc/backend/taler-merchant-httpd_get-config.c | 2+-
Msrc/backend/taler-merchant-httpd_helper.c | 8++++----
Msrc/backend/taler-merchant-httpd_patch-private-products-PRODUCT_ID.c | 4++--
Msrc/backend/taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c | 4++--
Msrc/backend/taler-merchant-httpd_post-orders-ORDER_ID-paid.c | 4++--
Msrc/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c | 4++--
Msrc/backend/taler-merchant-httpd_post-private-groups.c | 4++--
Msrc/backend/taler-merchant-httpd_post-private-orders.c | 12++++++------
Msrc/backend/taler-merchant-httpd_post-private-pots.c | 4++--
Msrc/backend/taler-merchant-httpd_post-private-products.c | 4++--
Msrc/backend/taler-merchant-httpd_post-private-templates.c | 4++--
Msrc/include/taler/taler_merchant_util.h | 32++++++++++++++++++++++++++++++++
Msrc/lib/merchant_api_common.c | 2+-
Msrc/lib/merchant_api_common_mfa_challenge.c | 5+++--
Msrc/lib/merchant_api_get-config.c | 4++--
Msrc/lib/merchant_api_get-management-instances.c | 4++--
Msrc/lib/merchant_api_get-orders-ORDER_ID.c | 2+-
Msrc/lib/merchant_api_get-private-orders-ORDER_ID.c | 2+-
Msrc/lib/merchant_api_get-private-orders.c | 4++--
Msrc/lib/merchant_api_get-private-otp-devices.c | 4++--
Msrc/lib/merchant_api_get-private-products-PRODUCT_ID.c | 2+-
Msrc/lib/merchant_api_get-private-products.c | 4++--
Msrc/lib/merchant_api_get-private-templates-TEMPLATE_ID.c | 4++--
Msrc/lib/merchant_api_get-private-templates.c | 4++--
Msrc/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c | 4++--
Msrc/lib/merchant_api_get-private-units-UNIT.c | 4++--
Msrc/lib/merchant_api_get-private-units.c | 4++--
Msrc/lib/merchant_api_get-private-webhooks.c | 4++--
Msrc/lib/merchant_api_post-private-orders.c | 2+-
Msrc/testing/test_merchant_order_creation.sh | 4++--
Msrc/testing/test_merchant_product_creation.sh | 4++--
Msrc/testing/testing_api_cmd_pay_order.c | 4++--
Msrc/testing/testing_api_cmd_post_orders_paid.c | 4++--
Msrc/util/contract_choice_parse.c | 8++++----
Msrc/util/order_choice_parse.c | 12++++++++----
Msrc/util/product_parse.c | 8++++----
36 files changed, 113 insertions(+), 76 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_get-config.c b/src/backend/taler-merchant-httpd_get-config.c @@ -44,7 +44,7 @@ * #MERCHANT_PROTOCOL_CURRENT and #MERCHANT_PROTOCOL_AGE in * merchant_api_get_config.c! */ -#define MERCHANT_PROTOCOL_VERSION "33:0:21" +#define MERCHANT_PROTOCOL_VERSION "34:0:22" /** diff --git a/src/backend/taler-merchant-httpd_helper.c b/src/backend/taler-merchant-httpd_helper.c @@ -395,8 +395,8 @@ TMH_products_array_valid (const json_t *products) struct GNUNET_TIME_Timestamp delivery_date = { 0 }; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("product_id", - &product_id), + TALER_JSON_spec_slug ("product_id", + &product_id), NULL), TALER_JSON_spec_i18n_str ("description", &description), @@ -409,8 +409,8 @@ TMH_products_array_valid (const json_t *products) &unit_quantity), &unit_quantity_missing), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("unit", - &unit), + TALER_JSON_spec_slug ("unit", + &unit), NULL), GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_amount_any ("price", diff --git a/src/backend/taler-merchant-httpd_patch-private-products-PRODUCT_ID.c b/src/backend/taler-merchant-httpd_patch-private-products-PRODUCT_ID.c @@ -71,8 +71,8 @@ TMH_private_patch_products_ID ( GNUNET_JSON_spec_json ("description_i18n", &pd.description_i18n), NULL), - GNUNET_JSON_spec_string ("unit", - (const char **) &pd.unit), + TALER_JSON_spec_slug ("unit", + (const char **) &pd.unit), // FIXME: deprecated API GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_amount_any ("price", diff --git a/src/backend/taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c b/src/backend/taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c @@ -50,8 +50,8 @@ TMH_private_patch_templates_ID (const struct TMH_RequestHandler *rh, GNUNET_JSON_spec_string ("template_description", (const char **) &tp.template_description), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("otp_id", - (const char **) &tp.otp_id), + TALER_JSON_spec_slug ("otp_id", + (const char **) &tp.otp_id), NULL), GNUNET_JSON_spec_json ("template_contract", &tp.template_contract), diff --git a/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-paid.c b/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-paid.c @@ -85,8 +85,8 @@ TMH_post_orders_ID_paid (const struct TMH_RequestHandler *rh, &merchant_sig), GNUNET_JSON_spec_fixed_auto ("h_contract", &hct), - GNUNET_JSON_spec_string ("session_id", - &session_id), + TALER_JSON_spec_slug ("session_id", + &session_id), GNUNET_JSON_spec_end () }; enum GNUNET_GenericReturnValue res; diff --git a/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c @@ -5000,8 +5000,8 @@ phase_parse_pay (struct PayContext *pc) GNUNET_JSON_spec_array_const ("coins", &coins), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("session_id", - &session_id), + TALER_JSON_spec_slug ("session_id", + &session_id), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_object_const ("wallet_data", diff --git a/src/backend/taler-merchant-httpd_post-private-groups.c b/src/backend/taler-merchant-httpd_post-private-groups.c @@ -36,8 +36,8 @@ TMH_private_post_groups (const struct TMH_RequestHandler *rh, enum GNUNET_DB_QueryStatus qs; uint64_t group_id; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_slug ("group_name", - &group_name), + GNUNET_JSON_spec_string ("group_name", + &group_name), GNUNET_JSON_spec_string ("description", &description), GNUNET_JSON_spec_end () diff --git a/src/backend/taler-merchant-httpd_post-private-orders.c b/src/backend/taler-merchant-httpd_post-private-orders.c @@ -4065,8 +4065,8 @@ phase_parse_request (struct OrderContext *oc) &ip), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("session_id", - &oc->parse_request.session_id), + TALER_JSON_spec_slug ("session_id", + &oc->parse_request.session_id), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_array_const ("lock_uuids", @@ -4077,8 +4077,8 @@ phase_parse_request (struct OrderContext *oc) &create_token), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("otp_id", - &otp_id), + TALER_JSON_spec_slug ("otp_id", + &otp_id), NULL), GNUNET_JSON_spec_end () }; @@ -4197,8 +4197,8 @@ phase_parse_request (struct OrderContext *oc) const char *error_name; unsigned int error_line; struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_string ("product_id", - &ipr->product_id), + TALER_JSON_spec_slug ("product_id", + &ipr->product_id), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint64 ("quantity", &ipr->quantity), diff --git a/src/backend/taler-merchant-httpd_post-private-pots.c b/src/backend/taler-merchant-httpd_post-private-pots.c @@ -36,8 +36,8 @@ TMH_private_post_pots (const struct TMH_RequestHandler *rh, enum GNUNET_DB_QueryStatus qs; uint64_t pot_id; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_slug ("pot_name", - &pot_name), + GNUNET_JSON_spec_string ("pot_name", + &pot_name), GNUNET_JSON_spec_string ("description", &description), GNUNET_JSON_spec_end () diff --git a/src/backend/taler-merchant-httpd_post-private-products.c b/src/backend/taler-merchant-httpd_post-private-products.c @@ -62,8 +62,8 @@ TMH_private_post_products (const struct TMH_RequestHandler *rh, GNUNET_JSON_spec_json ("description_i18n", &pd.description_i18n), NULL), - GNUNET_JSON_spec_string ("unit", - (const char **) &pd.unit), + TALER_JSON_spec_slug ("unit", + (const char **) &pd.unit), GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_amount_any ("price", &price), diff --git a/src/backend/taler-merchant-httpd_post-private-templates.c b/src/backend/taler-merchant-httpd_post-private-templates.c @@ -76,8 +76,8 @@ TMH_private_post_templates (const struct TMH_RequestHandler *rh, GNUNET_JSON_spec_string ("template_description", (const char **) &tp.template_description), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("otp_id", - (const char **) &tp.otp_id), + TALER_JSON_spec_slug ("otp_id", + (const char **) &tp.otp_id), NULL), GNUNET_JSON_spec_json ("template_contract", &tp.template_contract), diff --git a/src/include/taler/taler_merchant_util.h b/src/include/taler/taler_merchant_util.h @@ -716,6 +716,14 @@ struct TALER_MERCHANT_OrderChoice bool no_max_fee; /** + * True if the client may replace @e amount when instantiating the + * template this choice belongs to; @e amount then merely provides the + * default. Only meaningful for choices from a template contract, + * never serialized into an order. + */ + bool editable_amount; + + /** * List of inputs the wallet must provision (all of them) to satisfy the * conditions for the order. */ @@ -1011,6 +1019,30 @@ struct TALER_MERCHANT_TemplateContract bool no_amount; /** + * Smallest amount the client may end up paying (excluding tips) + * when instantiating this template. Only checked against amounts + * the client had an influence on. + */ + struct TALER_Amount min_amount; + + /** + * True if @e min_amount was not provided. + */ + bool no_min_amount; + + /** + * Largest amount the client may end up paying (excluding tips) + * when instantiating this template. Only checked against amounts + * the client had an influence on. + */ + struct TALER_Amount max_amount; + + /** + * True if @e max_amount was not provided. + */ + bool no_max_amount; + + /** * Template allows tips. */ bool request_tip; diff --git a/src/lib/merchant_api_common.c b/src/lib/merchant_api_common.c @@ -532,7 +532,7 @@ TALER_MERCHANT_handle_order_creation_response_ ( bool aq_frac_missing; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ( + TALER_JSON_spec_slug ( "product_id", &por.details.gone.product_id), GNUNET_JSON_spec_uint64 ( diff --git a/src/lib/merchant_api_common_mfa_challenge.c b/src/lib/merchant_api_common_mfa_challenge.c @@ -22,6 +22,7 @@ #include "platform.h" #include "taler/taler_merchant_service.h" #include <gnunet/gnunet_json_lib.h> +#include "taler/taler_json_lib.h" #include "merchant_api_common.h" @@ -69,8 +70,8 @@ TALER_MERCHANT_parse_mfa_challenge_response_ ( &entry->tan_info), GNUNET_JSON_spec_string ("tan_channel", &entry->tan_channel), - GNUNET_JSON_spec_string ("challenge_id", - &entry->challenge_id), + TALER_JSON_spec_slug ("challenge_id", + &entry->challenge_id), GNUNET_JSON_spec_end () }; diff --git a/src/lib/merchant_api_get-config.c b/src/lib/merchant_api_get-config.c @@ -34,12 +34,12 @@ * Which version of the Taler protocol is implemented * by this library? Used to determine compatibility. */ -#define MERCHANT_PROTOCOL_CURRENT 33 +#define MERCHANT_PROTOCOL_CURRENT 34 /** * How many configs are we backwards-compatible with? */ -#define MERCHANT_PROTOCOL_AGE 9 +#define MERCHANT_PROTOCOL_AGE 10 /** * How many exchanges do we allow at most per merchant? diff --git a/src/lib/merchant_api_get-management-instances.c b/src/lib/merchant_api_get-management-instances.c @@ -108,8 +108,8 @@ parse_instances (const json_t *ia, struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("name", &ii->name), - GNUNET_JSON_spec_string ("id", - &ii->id), + TALER_JSON_spec_slug ("id", + &ii->id), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &ii->merchant_pub), GNUNET_JSON_spec_array_const ("payment_targets", diff --git a/src/lib/merchant_api_get-orders-ORDER_ID.c b/src/lib/merchant_api_get-orders-ORDER_ID.c @@ -213,7 +213,7 @@ handle_get_order_finished (void *cls, "taler_pay_uri", &owgr.details.payment_required.taler_pay_uri), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ( + TALER_JSON_spec_slug ( "already_paid_order_id", &owgr.details.payment_required.already_paid_order_id), NULL), diff --git a/src/lib/merchant_api_get-private-orders-ORDER_ID.c b/src/lib/merchant_api_get-private-orders-ORDER_ID.c @@ -125,7 +125,7 @@ handle_unpaid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, { struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ( + TALER_JSON_spec_slug ( "already_paid_order_id", &osr->details.ok.details.unpaid.already_paid_order_id), NULL), diff --git a/src/lib/merchant_api_get-private-orders.c b/src/lib/merchant_api_get-private-orders.c @@ -177,8 +177,8 @@ parse_orders (const json_t *ia, json_array_foreach (ia, index, value) { struct TALER_MERCHANT_GetPrivateOrdersOrderEntry *ie = &oes[index]; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("order_id", - &ie->order_id), + TALER_JSON_spec_slug ("order_id", + &ie->order_id), GNUNET_JSON_spec_timestamp ("timestamp", &ie->timestamp), GNUNET_JSON_spec_uint64 ("row_id", diff --git a/src/lib/merchant_api_get-private-otp-devices.c b/src/lib/merchant_api_get-private-otp-devices.c @@ -103,8 +103,8 @@ parse_otp_devices (const json_t *ia, struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry *ie = &otp[index]; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("otp_device_id", - &ie->otp_device_id), + TALER_JSON_spec_slug ("otp_device_id", + &ie->otp_device_id), GNUNET_JSON_spec_string ("device_description", &ie->otp_device_description), GNUNET_JSON_spec_end () diff --git a/src/lib/merchant_api_get-private-products-PRODUCT_ID.c b/src/lib/merchant_api_get-private-products-PRODUCT_ID.c @@ -113,7 +113,7 @@ handle_get_product_finished (void *cls, GNUNET_JSON_spec_object_const ( "description_i18n", &pgr.details.ok.description_i18n), - GNUNET_JSON_spec_string ( + TALER_JSON_spec_slug ( "unit", &pgr.details.ok.unit), TALER_JSON_spec_amount_any_array ( diff --git a/src/lib/merchant_api_get-private-products.c b/src/lib/merchant_api_get-private-products.c @@ -144,8 +144,8 @@ parse_products (const json_t *ia, struct TALER_MERCHANT_GetPrivateProductsInventoryEntry *ie = &ies[index]; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("product_id", - &ie->product_id), + TALER_JSON_spec_slug ("product_id", + &ie->product_id), GNUNET_JSON_spec_uint64 ("product_serial", &ie->product_serial), GNUNET_JSON_spec_end () diff --git a/src/lib/merchant_api_get-private-templates-TEMPLATE_ID.c b/src/lib/merchant_api_get-private-templates-TEMPLATE_ID.c @@ -105,8 +105,8 @@ handle_get_template_finished (void *cls, GNUNET_JSON_spec_string ("template_description", &tgr.details.ok.template_description), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("otp_id", - &tgr.details.ok.otp_id), + TALER_JSON_spec_slug ("otp_id", + &tgr.details.ok.otp_id), NULL), GNUNET_JSON_spec_object_const ("template_contract", &contract), diff --git a/src/lib/merchant_api_get-private-templates.c b/src/lib/merchant_api_get-private-templates.c @@ -104,8 +104,8 @@ parse_templates (const json_t *ia, struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry *ie = &tmpl[index]; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("template_id", - &ie->template_id), + TALER_JSON_spec_slug ("template_id", + &ie->template_id), GNUNET_JSON_spec_string ("template_description", &ie->template_description), GNUNET_JSON_spec_end () diff --git a/src/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c b/src/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c @@ -102,8 +102,8 @@ handle_get_token_family_finished (void *cls, case MHD_HTTP_OK: { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("slug", - &tfgr.details.ok.slug), + TALER_JSON_spec_slug ("slug", + &tfgr.details.ok.slug), GNUNET_JSON_spec_string ("name", &tfgr.details.ok.name), GNUNET_JSON_spec_string ("description", diff --git a/src/lib/merchant_api_get-private-units-UNIT.c b/src/lib/merchant_api_get-private-units-UNIT.c @@ -85,8 +85,8 @@ parse_unit (const json_t *json, { struct TALER_MERCHANT_UnitEntry *entry = &ugr->details.ok.unit; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("unit", - &entry->unit), + TALER_JSON_spec_slug ("unit", + &entry->unit), GNUNET_JSON_spec_string ("unit_name_long", &entry->unit_name_long), GNUNET_JSON_spec_string ("unit_name_short", diff --git a/src/lib/merchant_api_get-private-units.c b/src/lib/merchant_api_get-private-units.c @@ -85,8 +85,8 @@ parse_unit_entry (const json_t *value, struct TALER_MERCHANT_UnitEntry *ue) { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("unit", - &ue->unit), + TALER_JSON_spec_slug ("unit", + &ue->unit), GNUNET_JSON_spec_string ("unit_name_long", &ue->unit_name_long), GNUNET_JSON_spec_string ("unit_name_short", diff --git a/src/lib/merchant_api_get-private-webhooks.c b/src/lib/merchant_api_get-private-webhooks.c @@ -104,8 +104,8 @@ parse_webhooks (const json_t *ia, struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry *ie = &whook[index]; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("webhook_id", - &ie->webhook_id), + TALER_JSON_spec_slug ("webhook_id", + &ie->webhook_id), GNUNET_JSON_spec_string ("event_type", &ie->event_type), GNUNET_JSON_spec_end () diff --git a/src/lib/merchant_api_post-private-orders.c b/src/lib/merchant_api_post-private-orders.c @@ -224,7 +224,7 @@ handle_post_orders_finished (void *cls, bool rq_frac_missing; bool aq_frac_missing; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ( + TALER_JSON_spec_slug ( "product_id", &por.details.gone.product_id), GNUNET_JSON_spec_uint64 ( diff --git a/src/testing/test_merchant_order_creation.sh b/src/testing/test_merchant_order_creation.sh @@ -395,7 +395,7 @@ echo "OK" echo -n "Creating product..." STATUS=$(curl 'http://localhost:9966/private/products' \ - -d '{"product_id":"2","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"2","description_i18n":{},"unit":"","image":"'$RANDOM_IMG'","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ + -d '{"product_id":"2","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"2","description_i18n":{},"unit":"u","image":"'$RANDOM_IMG'","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] @@ -444,7 +444,7 @@ echo "OK" STATUS=$(curl 'http://localhost:9966/private/products' \ - -d '{"product_id":"1","description":"product with id 1 and price :15","unit_price":["USD:15"],"unit_total_stock":"1","description_i18n":{},"unit":"","image":"","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ + -d '{"product_id":"1","description":"product with id 1 and price :15","unit_price":["USD:15"],"unit_total_stock":"1","description_i18n":{},"unit":"u","image":"","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] diff --git a/src/testing/test_merchant_product_creation.sh b/src/testing/test_merchant_product_creation.sh @@ -89,8 +89,8 @@ fi echo "OK" RANDOM_IMG='data:image/png;base64,abcdefg' -INFINITE_PRODUCT_TEMPLATE='{"product_id":"2","product_name":"stuff","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"-1","unit":"","image":"'"$RANDOM_IMG"'","taxes":[]}' -MANAGED_PRODUCT_TEMPLATE='{"product_id":"3","product_name":"more stuff","description":"product with id 3 and price :10","unit_price":["TESTKUDOS:150"],"unit_total_stock":"2","unit":"","image":"'"$RANDOM_IMG"'","taxes":[]}' +INFINITE_PRODUCT_TEMPLATE='{"product_id":"2","product_name":"stuff","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"-1","unit":"u","image":"'"$RANDOM_IMG"'","taxes":[]}' +MANAGED_PRODUCT_TEMPLATE='{"product_id":"3","product_name":"more stuff","description":"product with id 3 and price :10","unit_price":["TESTKUDOS:150"],"unit_total_stock":"2","unit":"u","image":"'"$RANDOM_IMG"'","taxes":[]}' echo -n "Creating products..." STATUS=$(curl 'http://localhost:9966/private/products' \ diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c @@ -1210,8 +1210,8 @@ pay_run (void *cls, kind)) { struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_string ("token_family_slug", - &slug), + TALER_JSON_spec_slug ("token_family_slug", + &slug), GNUNET_JSON_spec_uint32 ("key_index", &key_index), GNUNET_JSON_spec_mark_optional ( diff --git a/src/testing/testing_api_cmd_post_orders_paid.c b/src/testing/testing_api_cmd_post_orders_paid.c @@ -150,8 +150,8 @@ paid_run (void *cls, /* Get information that needs to be put verbatim in the * deposit permission */ struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("order_id", - &order_id), + TALER_JSON_spec_slug ("order_id", + &order_id), GNUNET_JSON_spec_end () }; diff --git a/src/util/contract_choice_parse.c b/src/util/contract_choice_parse.c @@ -110,8 +110,8 @@ parse_contract_choice_input ( case TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN: { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("token_family_slug", - &input->details.token.token_family_slug), + TALER_JSON_spec_slug ("token_family_slug", + &input->details.token.token_family_slug), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint ("count", &input->details.token.count), @@ -191,8 +191,8 @@ parse_contract_choice_output ( case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN: { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("token_family_slug", - &output->details.token.token_family_slug), + TALER_JSON_spec_slug ("token_family_slug", + &output->details.token.token_family_slug), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint ("count", &output->details.token.count), diff --git a/src/util/order_choice_parse.c b/src/util/order_choice_parse.c @@ -75,8 +75,8 @@ parse_order_choice_input ( case TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN: { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("token_family_slug", - &input->details.token.token_family_slug), + TALER_JSON_spec_slug ("token_family_slug", + &input->details.token.token_family_slug), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint ("count", &input->details.token.count), @@ -156,8 +156,8 @@ parse_order_choice_output ( case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN: { struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("token_family_slug", - &output->details.token.token_family_slug), + TALER_JSON_spec_slug ("token_family_slug", + &output->details.token.token_family_slug), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint ("count", &output->details.token.count), @@ -281,6 +281,10 @@ parse_order_choices ( &choice->max_fee), &choice->no_max_fee), GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_bool ("editable_amount", + &choice->editable_amount), + NULL), + GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_array_const ("inputs", &jinputs), NULL), diff --git a/src/util/product_parse.c b/src/util/product_parse.c @@ -128,8 +128,8 @@ TALER_MERCHANT_parse_product_sold (const json_t *pj, const json_t *prices = NULL; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string_copy ("product_id", - &r->product_id), + TALER_JSON_spec_slug_copy ("product_id", + &r->product_id), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string_copy ("product_name", @@ -156,8 +156,8 @@ TALER_MERCHANT_parse_product_sold (const json_t *pj, &unit_quantity_s), &no_unit_quantity), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string_copy ("unit", - &r->unit), + TALER_JSON_spec_slug_copy ("unit", + &r->unit), NULL), GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_amount_any ("price",