merchant

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

commit cdadb3079037c3ed2cf91edc16934d4a841a55b2
parent dc6dec302b54cf07dfe6aea32892d362d2beaab0
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 25 Mar 2026 21:14:25 +0100

more libtalermerchant API refactoring to make it consistent with the actual REST API

Diffstat:
Mcontrib/uncrustify.cfg | 2+-
Msrc/include/taler/taler-merchant/get-config.h | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/include/taler/taler-merchant/get-private-kyc.h | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/include/taler/taler-merchant/patch-management-instances-INSTANCE.h | 308++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/include/taler/taler-merchant/patch-private-accounts-H_WIRE.h | 27++++++++++++++++++++++++++-
Msrc/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/include/taler/taler-merchant/patch-private-products-PRODUCT_ID.h | 404+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/include/taler/taler-merchant/post-management-instances.h | 330++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/include/taler/taler-merchant/post-orders-ORDER_ID-paid.h | 26++++++++++++++++++++++++++
Msrc/include/taler/taler-merchant/post-private-accounts.h | 27++++++++++++++++++++++++++-
Msrc/include/taler/taler-merchant/post-private-otp-devices.h | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/include/taler/taler-merchant/post-private-products.h | 211++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/include/taler/taler-merchant/post-private-templates.h | 28+++++++++++++++++++++++++++-
Msrc/include/taler/taler-merchant/post-private-token.h | 190++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/include/taler/taler-merchant/post-private-units.h | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/include/taler/taler-merchant/post-private-webhooks.h | 150++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/lib/merchant_api_get-config.c | 38++++++++++++++++++++++++++++++++++++++
Msrc/lib/merchant_api_get-private-kyc.c | 100++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/lib/merchant_api_get-private-otp-devices-DEVICE_ID.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/merchant_api_patch-management-instances-INSTANCE.c | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/lib/merchant_api_patch-private-accounts-H_WIRE.c | 32+++++++++++++++++++++++++-------
Msrc/lib/merchant_api_patch-private-otp-devices-DEVICE_ID.c | 44++++++++++++++++++++++++++++++++++++++------
Msrc/lib/merchant_api_patch-private-products-PRODUCT_ID.c | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/lib/merchant_api_patch-private-templates-TEMPLATE_ID.c | 36+++++++++++++++++++++++++++++++++++-
Msrc/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID.c | 57++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/lib/merchant_api_post-management-instances.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/lib/merchant_api_post-orders-ORDER_ID-paid.c | 21+++++++++++++++++++++
Msrc/lib/merchant_api_post-private-accounts.c | 34++++++++++++++++++++++++++--------
Msrc/lib/merchant_api_post-private-otp-devices.c | 34+++++++++++++++++++++++++++++++---
Msrc/lib/merchant_api_post-private-products.c | 201+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/lib/merchant_api_post-private-templates.c | 15++++++++++++++-
Msrc/lib/merchant_api_post-private-token.c | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/lib/merchant_api_post-private-transfers.c | 4++++
Msrc/lib/merchant_api_post-private-units.c | 47+++++++++++++++++++++++++++++++++++++----------
Msrc/lib/merchant_api_post-private-webhooks.c | 53++++++++++++++++++++++++++++++++++++++---------------
Msrc/testing/testing_api_cmd_instance_token.c | 53+++++++++++------------------------------------------
Msrc/testing/testing_api_cmd_patch_instance.c | 17++++++++++++-----
Msrc/testing/testing_api_cmd_patch_otp_device.c | 7+++++--
Msrc/testing/testing_api_cmd_patch_product.c | 42++++++++++++++++--------------------------
Msrc/testing/testing_api_cmd_patch_webhook.c | 14+++++++++++---
Msrc/testing/testing_api_cmd_post_instances.c | 18++++++++++++------
Msrc/testing/testing_api_cmd_post_otp_devices.c | 8++++++--
Msrc/testing/testing_api_cmd_post_products.c | 84++++++++++++++++++++++++++++++-------------------------------------------------
Msrc/testing/testing_api_cmd_post_units.c | 13+++++++++----
Msrc/testing/testing_api_cmd_post_webhooks.c | 14+++++++++++---
48 files changed, 3769 insertions(+), 543 deletions(-)

diff --git a/contrib/uncrustify.cfg b/contrib/uncrustify.cfg @@ -6,7 +6,7 @@ indent_with_tabs = 0 indent_case_brace = 2 indent_label=-16 -code_width=80 +code_width=100 #cmd_width=80 # Leave most comments alone for now diff --git a/src/include/taler/taler-merchant/get-config.h b/src/include/taler/taler-merchant/get-config.h @@ -161,6 +161,80 @@ struct TALER_MERCHANT_GetConfigResponse const char *version; } ci; + /** + * Implementation identifier (e.g. + * "urn:net:taler:specs:taler-merchant:c-reference"). + * NULL if not provided. + */ + const char *implementation; + + /** + * Whether the backend supports self-provisioning. + */ + bool have_self_provisioning; + + /** + * Whether the backend was compiled with Donau support. + */ + bool have_donau; + + /** + * Allowed payment target types (as a string). + * NULL if not provided. + */ + const char *payment_target_types; + + /** + * Payment target regex (as a string). + * NULL if not provided. + */ + const char *payment_target_regex; + + /** + * Mandatory TAN channels (JSON array of strings). + * NULL if not provided. + */ + const json_t *mandatory_tan_channels; + + /** + * Default pay delay. + */ + struct GNUNET_TIME_Relative default_pay_delay; + + /** + * Default refund delay. + */ + struct GNUNET_TIME_Relative default_refund_delay; + + /** + * Default wire transfer delay. + */ + struct GNUNET_TIME_Relative default_wire_transfer_delay; + + /** + * Default persona. + */ + const char *default_persona; + + /** + * Report generators (JSON array of strings). + * NULL if not provided. + * // FIXME: split up into array of strings? + */ + const json_t *report_generators; + + /** + * Phone regex for validation. + * NULL if not provided. + */ + const char *phone_regex; + + /** + * SPA configuration options (JSON object). + * NULL if not provided. + */ + const json_t *spa_options; + } ok; } details; diff --git a/src/include/taler/taler-merchant/get-private-kyc.h b/src/include/taler/taler-merchant/get-private-kyc.h @@ -59,7 +59,25 @@ enum TALER_MERCHANT_GetPrivateKycOption * Instance ID for management mode (GET /management/instances/$INSTANCE/kyc). * If not set, uses the private endpoint (GET /private/kyc). */ - TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID, + + /** + * Long-poll status filter: only return when some account reaches + * this status. String value (since v25). + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_STATUS, + + /** + * Long-poll negated status filter: only return when some account + * no longer matches this status. String value (since v25). + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_STATUS, + + /** + * Long-poll ETag to suppress responses that have not changed. + * ShortHashCode value (since v25). + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_ETAG }; @@ -114,6 +132,24 @@ struct TALER_MERCHANT_GetPrivateKycOptionValue */ const char *instance_id; + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_STATUS. + */ + const char *lp_status; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_STATUS. + */ + const char *lp_not_status; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_ETAG. + */ + const struct GNUNET_ShortHashCode *lp_not_etag; + } details; }; @@ -220,6 +256,45 @@ TALER_MERCHANT_get_private_kyc_create ( .details.instance_id = (id) \ } +/** + * Set long-poll status filter. + * + * @param s status string to wait for + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_lp_status(s) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_STATUS, \ + .details.lp_status = (s) \ + } + +/** + * Set long-poll negated status filter. + * + * @param s status string to negate + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_lp_not_status(s) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_STATUS, \ + .details.lp_not_status = (s) \ + } + +/** + * Set long-poll ETag to suppress unchanged responses. + * + * @param e pointer to the short hash code ETag + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_lp_not_etag(e) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_ETAG, \ + .details.lp_not_etag = (e) \ + } + /** * Set the requested options for the operation. diff --git a/src/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h b/src/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h @@ -92,6 +92,63 @@ struct TALER_MERCHANT_GetPrivateOtpDeviceResponse /** + * Possible options we can set for the GET /private/otp-devices/$DEVICE_ID request. + */ +enum TALER_MERCHANT_GetPrivateOtpDeviceOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_END = 0, + + /** + * Set a fake time for OTP code computation. + */ + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_FAKETIME, + + /** + * Set a price amount for OTP code computation. + */ + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_PRICE + +}; + + +/** + * Value for an option for the GET /private/otp-devices/$DEVICE_ID request. + */ +struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateOtpDeviceOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_FAKETIME. + */ + struct GNUNET_TIME_Timestamp faketime; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_PRICE. + */ + struct TALER_Amount price; + + } details; + +}; + + +/** * Set up GET /private/otp-devices/$DEVICE_ID operation. * Note that you must explicitly start the operation after * possibly setting options. @@ -108,6 +165,93 @@ TALER_MERCHANT_get_private_otp_device_create ( const char *otp_device_id); +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue + */ +#define TALER_MERCHANT_get_private_otp_device_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_END \ + } + +/** + * Set a fake time for OTP code computation. + * + * @param t the timestamp to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue + */ +#define TALER_MERCHANT_get_private_otp_device_option_faketime(t) \ + (const struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_FAKETIME, \ + .details.faketime = (t) \ + } + +/** + * Set a price amount for OTP code computation. + * + * @param a the amount to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue + */ +#define TALER_MERCHANT_get_private_otp_device_option_price(a) \ + (const struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_PRICE, \ + .details.price = (a) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param god the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_otp_device_set_options_ ( + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_get_private_otp_device_set_options ( + * god, + * TALER_MERCHANT_get_private_otp_device_option_faketime (ts), + * TALER_MERCHANT_get_private_otp_device_option_price (amount)); + * + * @param god the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_otp_device_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_otp_device_set_options(god,...) \ + TALER_MERCHANT_get_private_otp_device_set_options_ ( \ + god, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_get_private_otp_device_option_end_ () } \ + )) + + #ifndef TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE /** * Type of the closure used by diff --git a/src/include/taler/taler-merchant/patch-management-instances-INSTANCE.h b/src/include/taler/taler-merchant/patch-management-instances-INSTANCE.h @@ -26,6 +26,129 @@ /** + * Possible options we can set for the PATCH /management/instances/$INSTANCE request. + */ +enum TALER_MERCHANT_PatchManagementInstancesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_END = 0, + + /** + * Set the default pay delay. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY, + + /** + * Set the default refund delay. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY, + + /** + * Set the default wire transfer delay. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY, + + /** + * Set the default wire transfer rounding interval. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL, + + /** + * Set the email address. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_EMAIL, + + /** + * Set the phone number. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER, + + /** + * Set the website URL. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_WEBSITE, + + /** + * Set the logo. + */ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_LOGO + +}; + + +/** + * Value for an option for the PATCH /management/instances/$INSTANCE request. + */ +struct TALER_MERCHANT_PatchManagementInstancesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchManagementInstancesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY. + */ + struct GNUNET_TIME_Relative default_pay_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY. + */ + struct GNUNET_TIME_Relative default_refund_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY. + */ + struct GNUNET_TIME_Relative default_wire_transfer_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL. + */ + enum GNUNET_TIME_RounderInterval default_wire_transfer_rounding_interval; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_EMAIL. + */ + const char *email; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER. + */ + const char *phone_number; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_WEBSITE. + */ + const char *website; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_LOGO. + */ + const char *logo; + + } details; + +}; + + +/** * Handle for a PATCH /management/instances/$INSTANCE operation. */ struct TALER_MERCHANT_PatchManagementInstancesHandle; @@ -33,7 +156,8 @@ struct TALER_MERCHANT_PatchManagementInstancesHandle; /** * Set up PATCH /management/instances/$INSTANCE operation. - * Note that you must explicitly start the operation after setup. + * Note that you must explicitly start the operation after + * possibly setting options. * * @param ctx the context * @param url base URL of the merchant backend @@ -42,9 +166,6 @@ struct TALER_MERCHANT_PatchManagementInstancesHandle; * @param address new address (JSON) * @param jurisdiction new jurisdiction (JSON) * @param use_stefan whether to use the STEFAN curve for fee calculations - * @param default_wire_transfer_delay default delay for wire transfers - * @param default_pay_delay default payment deadline - * @param default_refund_delay default refund deadline * @return handle to operation, NULL on error */ struct TALER_MERCHANT_PatchManagementInstancesHandle * @@ -55,10 +176,181 @@ TALER_MERCHANT_patch_management_instances_create ( const char *name, const json_t *address, const json_t *jurisdiction, - bool use_stefan, - struct GNUNET_TIME_Relative default_wire_transfer_delay, - struct GNUNET_TIME_Relative default_pay_delay, - struct GNUNET_TIME_Relative default_refund_delay); + bool use_stefan); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PatchManagementInstancesOptionValue + */ +#define TALER_MERCHANT_patch_management_instances_option_end_() \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_END \ + } + +/** + * Set default pay delay. + * + * @param d delay to set + * @return representation of the option + */ +#define TALER_MERCHANT_patch_management_instances_option_default_pay_delay(d) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY, \ + .details.default_pay_delay = (d) \ + } + +/** + * Set default refund delay. + * + * @param d delay to set + * @return representation of the option + */ +#define TALER_MERCHANT_patch_management_instances_option_default_refund_delay(d) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY, \ + .details.default_refund_delay = (d) \ + } + +/** + * Set default wire transfer delay. + * + * @param d delay to set + * @return representation of the option + */ +#define \ + TALER_MERCHANT_patch_management_instances_option_default_wire_transfer_delay(d) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY, \ + .details.default_wire_transfer_delay = (d) \ + } + +/** + * Set default wire transfer rounding interval. + * + * @param ri rounding interval to set + * @return representation of the option + */ +#define \ + TALER_MERCHANT_patch_management_instances_option_default_wire_transfer_rounding_interval(ri) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL, \ + .details.default_wire_transfer_rounding_interval = (ri) \ + } + +/** + * Set email address. + * + * @param e email to set + * @return representation of the option + */ +#define TALER_MERCHANT_patch_management_instances_option_email(e) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_EMAIL, \ + .details.email = (e) \ + } + +/** + * Set phone number. + * + * @param p phone number to set + * @return representation of the option + */ +#define TALER_MERCHANT_patch_management_instances_option_phone_number(p) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER, \ + .details.phone_number = (p) \ + } + +/** + * Set website URL. + * + * @param w website to set + * @return representation of the option + */ +#define TALER_MERCHANT_patch_management_instances_option_website(w) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_WEBSITE, \ + .details.website = (w) \ + } + +/** + * Set logo. + * + * @param l logo to set + * @return representation of the option + */ +#define TALER_MERCHANT_patch_management_instances_option_logo(l) \ + (const struct TALER_MERCHANT_PatchManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_LOGO, \ + .details.logo = (l) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param pmih the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_management_instances_set_options_ ( + struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih, + unsigned int num_options, + const struct TALER_MERCHANT_PatchManagementInstancesOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_patch_management_instances_set_options ( + * pmih, + * TALER_MERCHANT_patch_management_instances_option_email ( + * "foo@example.com")); + * + * @param pmih the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_patch_management_instances_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_management_instances_set_options(pmih,...) \ + TALER_MERCHANT_patch_management_instances_set_options_ ( \ + pmih, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchManagementInstancesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_management_instances_option_end_ \ + () } \ + )) /** diff --git a/src/include/taler/taler-merchant/patch-private-accounts-H_WIRE.h b/src/include/taler/taler-merchant/patch-private-accounts-H_WIRE.h @@ -43,7 +43,12 @@ enum TALER_MERCHANT_PatchPrivateAccountOption /** * Set the credit facade credentials (JSON). */ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS, + + /** + * Set the extra wire subject metadata (restricted text). + */ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_EXTRA_WIRE_SUBJECT_METADATA }; @@ -77,6 +82,12 @@ struct TALER_MERCHANT_PatchPrivateAccountOptionValue */ const json_t *credit_facade_credentials; + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_EXTRA_WIRE_SUBJECT_METADATA. + */ + const char *extra_wire_subject_metadata; + } details; }; @@ -144,6 +155,20 @@ TALER_MERCHANT_patch_private_account_create ( .details.credit_facade_credentials = (c) \ } +/** + * Set extra wire subject metadata. + * + * @param m extra wire subject metadata (JSON) to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateAccountOptionValue + */ +#define TALER_MERCHANT_patch_private_account_option_extra_wire_subject_metadata(m) \ + (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_EXTRA_WIRE_SUBJECT_METADATA, \ + .details.extra_wire_subject_metadata = (m) \ + } + /** * Set the requested options for the operation. diff --git a/src/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h b/src/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h @@ -26,6 +26,52 @@ /** + * Possible options we can set for the PATCH /private/otp-devices/$DEVICE_ID request. + */ +enum TALER_MERCHANT_PatchPrivateOtpDeviceOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_END = 0, + + /** + * Set the OTP counter value (for HOTP). + */ + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_OTP_CTR + +}; + + +/** + * Value for an option for the PATCH /private/otp-devices/$DEVICE_ID request. + */ +struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchPrivateOtpDeviceOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_OTP_CTR. + */ + uint64_t otp_ctr; + + } details; + +}; + + +/** * Handle for a PATCH /private/otp-devices/$DEVICE_ID operation. */ struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle; @@ -41,7 +87,6 @@ struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle; * @param otp_device_description new human-readable description * @param otp_key new base32-encoded OTP secret key, or NULL to keep unchanged * @param mca new OTP algorithm - * @param otp_ctr new counter value (for HOTP) * @return handle to operation, NULL on error */ struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle * @@ -51,8 +96,79 @@ TALER_MERCHANT_patch_private_otp_device_create ( const char *otp_device_id, const char *otp_device_description, const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm mca, - uint64_t otp_ctr); + enum TALER_MerchantConfirmationAlgorithm mca); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue + */ +#define TALER_MERCHANT_patch_private_otp_device_option_end_() \ + (const struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_END \ + } + +/** + * Set the counter value (for HOTP). + * + * @param c the counter value + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue + */ +#define TALER_MERCHANT_patch_private_otp_device_option_otp_ctr(c) \ + (const struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_OTP_CTR, \ + .details.otp_ctr = (c) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param odh the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_otp_device_set_options_ ( + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_patch_private_otp_device_set_options ( + * odh, + * TALER_MERCHANT_patch_private_otp_device_option_otp_ctr (42)); + * + * @param odh the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_patch_private_otp_device_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_private_otp_device_set_options(odh,...) \ + TALER_MERCHANT_patch_private_otp_device_set_options_ ( \ + odh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_private_otp_device_option_end_ () } \ + )) /** diff --git a/src/include/taler/taler-merchant/patch-private-products-PRODUCT_ID.h b/src/include/taler/taler-merchant/patch-private-products-PRODUCT_ID.h @@ -36,9 +36,14 @@ enum TALER_MERCHANT_PatchPrivateProductOption TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_END = 0, /** - * Set unit prices array (for patch2 variant with full unit/fraction support). + * Set value and fractional part of total stock. */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES, + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK, + + /** + * Set value part of total stock (-1 for unlimited). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_VAL, /** * Set fractional part of total stock. @@ -53,7 +58,67 @@ enum TALER_MERCHANT_PatchPrivateProductOption /** * Set precision level for fractions. */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL, + + /** + * Internationalized descriptions (JSON). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_DESCRIPTION_I18N, + + /** + * Product image (base64-encoded data URL). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_IMAGE, + + /** + * Tax information (JSON array). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TAXES, + + /** + * Total units lost/expired. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_LOST, + + /** + * Storage location (JSON). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_ADDRESS, + + /** + * Expected restock time. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_NEXT_RESTOCK, + + /** + * Explicit product name (distinct from description). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_NAME, + + /** + * Category IDs. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_CATEGORIES, + + /** + * Minimum age requirement. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MINIMUM_AGE, + + /** + * Product group ID. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_GROUP_ID, + + /** + * Money pot ID. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MONEY_POT_ID, + + /** + * Whether the price is net (before tax). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRICE_IS_NET }; @@ -77,39 +142,114 @@ struct TALER_MERCHANT_PatchPrivateProductOptionValue /** * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES. + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC. + */ + uint32_t total_stock_frac; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION. + */ + bool unit_allow_fraction; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL. + */ + uint32_t unit_precision_level; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_DESCRIPTION_I18N. + */ + const json_t *description_i18n; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_IMAGE. + */ + const char *image; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TAXES. */ + const json_t *taxes; + struct { + /** - * Array of unit prices. + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK. + * -1 for infinite stock. */ - const struct TALER_Amount *unit_prices; + int64_t val; /** - * Number of prices in @e unit_prices. + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC. */ - size_t unit_price_len; + uint32_t frac; + } total_stock; - } unit_prices; + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_LOST. + */ + uint64_t total_lost; /** * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC. + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_ADDRESS. */ - uint32_t total_stock_frac; + const json_t *address; /** * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION. + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_NEXT_RESTOCK. */ - bool unit_allow_fraction; + struct GNUNET_TIME_Timestamp next_restock; /** * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL. + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_NAME. */ - uint32_t unit_precision_level; + const char *product_name; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_CATEGORIES. + */ + struct + { + unsigned int num; + const uint64_t *cats; + } categories; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MINIMUM_AGE. + */ + uint32_t minimum_age; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_GROUP_ID. + */ + uint64_t product_group_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MONEY_POT_ID. + */ + uint64_t money_pot_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRICE_IS_NET. + */ + bool price_is_net; } details; @@ -131,15 +271,9 @@ struct TALER_MERCHANT_PatchPrivateProductHandle; * @param url base URL of the merchant backend * @param product_id identifier of the product to update * @param description new human-readable description - * @param description_i18n internationalized descriptions (JSON) * @param unit unit of measurement - * @param price new unit price - * @param image new base64-encoded image - * @param taxes new tax information (JSON array) - * @param total_stock new total stock (-1 for unlimited) - * @param total_lost total units lost/expired - * @param address storage location (JSON) - * @param next_restock expected restock time + * @param num_prices length of the @e prices array + * @param prices new unit prices * @return handle to operation, NULL on error */ struct TALER_MERCHANT_PatchPrivateProductHandle * @@ -148,15 +282,9 @@ TALER_MERCHANT_patch_private_product_create ( const char *url, const char *product_id, const char *description, - const json_t *description_i18n, const char *unit, - const struct TALER_Amount *price, - const char *image, - const json_t *taxes, - int64_t total_stock, - uint64_t total_lost, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock); + unsigned int num_prices, + const struct TALER_Amount prices[static num_prices]); /** @@ -171,17 +299,18 @@ TALER_MERCHANT_patch_private_product_create ( } /** - * Set unit prices array. + * Set value and fractional part of total stock. * - * @param p pointer to array of unit prices - * @param l number of prices in the array + * @param v value part of stock + * @param f fractional stock value * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateProductOptionValue */ -#define TALER_MERCHANT_patch_private_product_option_unit_prices(p,l) \ - (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES, \ - .details.unit_prices = { .unit_prices = (p), .unit_price_len = (l) } \ +#define TALER_MERCHANT_patch_private_product_option_total_stock(v,f) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC, \ + .details.total_stock.val = (v), \ + .details.total_stock.frac = (f) \ } /** @@ -190,12 +319,24 @@ TALER_MERCHANT_patch_private_product_create ( * @param f fractional stock value * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateProductOptionValue */ -#define TALER_MERCHANT_patch_private_product_option_total_stock_frac(f) \ - (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC \ - , \ - .details.total_stock_frac = (f) \ +#define TALER_MERCHANT_patch_private_product_option_total_stock_frac(f) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC, \ + .details.total_stock.frac = (f) \ + } + +/** + * Set value part of total stock (-1 for unlimited). + * + * @param v stock value + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateProductOptionValue + */ +#define TALER_MERCHANT_patch_private_product_option_total_stock_val(v) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_VAL, \ + .details.total_stock.val = (v) \ } /** @@ -204,12 +345,11 @@ TALER_MERCHANT_patch_private_product_create ( * @param a true if fractional quantities are allowed * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateProductOptionValue */ -#define TALER_MERCHANT_patch_private_product_option_unit_allow_fraction(a) \ - (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION, \ - .details.unit_allow_fraction = (a) \ +#define TALER_MERCHANT_patch_private_product_option_unit_allow_fraction(a) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION, \ + .details.unit_allow_fraction = (a) \ } /** @@ -226,6 +366,168 @@ TALER_MERCHANT_patch_private_product_create ( .details.unit_precision_level = (p) \ } +/** + * Set internationalized descriptions. + * + * @param d descriptions JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_description_i18n(d) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_DESCRIPTION_I18N, \ + .details.description_i18n = (d) \ + } + +/** + * Set product image (base64-encoded data URL). + * + * @param i image string + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_image(i) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_IMAGE, \ + .details.image = (i) \ + } + +/** + * Set tax information. + * + * @param t taxes JSON array + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_taxes(t) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TAXES, \ + .details.taxes = (t) \ + } + +/** + * Set total units lost/expired. + * + * @param l total lost value + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_total_lost(l) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_LOST, \ + .details.total_lost = (l) \ + } + +/** + * Set storage address. + * + * @param a address JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_address(a) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_ADDRESS, \ + .details.address = (a) \ + } + +/** + * Set expected restock time. + * + * @param r restock timestamp + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_next_restock(r) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_NEXT_RESTOCK, \ + .details.next_restock = (r) \ + } + +/** + * Set explicit product name (distinct from description). + * + * @param n product name string + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_product_name(n) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_NAME, \ + .details.product_name = (n) \ + } + +/** + * Set category IDs. + * + * @param n number of categories + * @param c array of category IDs + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_categories(n,c) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_CATEGORIES, \ + .details.categories = { .num = (n), .cats = (c) } \ + } + +/** + * Set minimum age requirement. + * + * @param a minimum age (0 for none) + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_minimum_age(a) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MINIMUM_AGE, \ + .details.minimum_age = (a) \ + } + +/** + * Set product group ID. + * + * @param g product group ID + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_product_group_id(g) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_GROUP_ID, \ + .details.product_group_id = (g) \ + } + +/** + * Set money pot ID. + * + * @param m money pot ID + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_money_pot_id(m) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MONEY_POT_ID, \ + .details.money_pot_id = (m) \ + } + +/** + * Set whether the price is net (before tax). + * + * @param b true if price is net + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_product_option_price_is_net(b) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRICE_IS_NET, \ + .details.price_is_net = (b) \ + } + /** * Set the requested options for the operation. diff --git a/src/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h b/src/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h @@ -26,6 +26,52 @@ /** + * Possible options for the PATCH /private/templates/$TEMPLATE_ID request. + */ +enum TALER_MERCHANT_PatchPrivateTemplateOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_END = 0, + + /** + * Editable defaults (JSON object) for the template. + */ + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_EDITABLE_DEFAULTS + +}; + + +/** + * Value for an option for the PATCH /private/templates/$TEMPLATE_ID request. + */ +struct TALER_MERCHANT_PatchPrivateTemplateOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchPrivateTemplateOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_EDITABLE_DEFAULTS. + */ + const json_t *editable_defaults; + + } details; + +}; + + +/** * Handle for a PATCH /private/templates/$TEMPLATE_ID operation. */ struct TALER_MERCHANT_PatchPrivateTemplateHandle; @@ -33,7 +79,8 @@ struct TALER_MERCHANT_PatchPrivateTemplateHandle; /** * Set up PATCH /private/templates/$TEMPLATE_ID operation. - * Note that you must explicitly start the operation after setup. + * Note that you must explicitly start the operation after + * possibly setting options. * * @param ctx the context * @param url base URL of the merchant backend @@ -54,6 +101,67 @@ TALER_MERCHANT_patch_private_template_create ( /** + * Terminate the list of the options. + * + * @return the terminating object + */ +#define TALER_MERCHANT_patch_private_template_option_end_() \ + (const struct TALER_MERCHANT_PatchPrivateTemplateOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_END \ + } + +/** + * Set editable defaults. + * + * @param ed editable defaults (JSON object) + * @return representation of the option + */ +#define TALER_MERCHANT_patch_private_template_option_editable_defaults(ed) \ + (const struct TALER_MERCHANT_PatchPrivateTemplateOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_EDITABLE_DEFAULTS, \ + .details.editable_defaults = (ed) \ + } + + +/** + * Set the requested options for the operation. + * + * @param tph the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_template_set_options_ ( + struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateTemplateOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param tph the request to set the options for + * @param ... the list of the options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_private_template_set_options(tph,...) \ + TALER_MERCHANT_patch_private_template_set_options_ ( \ + tph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchPrivateTemplateOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_private_template_option_end_ () } \ + )) + + +/** * Response details for a PATCH /private/templates/$TEMPLATE_ID request. */ struct TALER_MERCHANT_PatchPrivateTemplateResponse diff --git a/src/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h b/src/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h @@ -26,6 +26,63 @@ /** + * Possible options we can set for the PATCH /private/webhooks/$WEBHOOK_ID request. + */ +enum TALER_MERCHANT_PatchPrivateWebhookOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_END = 0, + + /** + * Set the header template. + */ + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_HEADER_TEMPLATE, + + /** + * Set the body template. + */ + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_BODY_TEMPLATE + +}; + + +/** + * Value for an option for the PATCH /private/webhooks/$WEBHOOK_ID request. + */ +struct TALER_MERCHANT_PatchPrivateWebhookOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchPrivateWebhookOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_HEADER_TEMPLATE. + */ + const char *header_template; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_BODY_TEMPLATE. + */ + const char *body_template; + + } details; + +}; + + +/** * Handle for a PATCH /private/webhooks/$WEBHOOK_ID operation. */ struct TALER_MERCHANT_PatchPrivateWebhookHandle; @@ -33,7 +90,8 @@ struct TALER_MERCHANT_PatchPrivateWebhookHandle; /** * Set up PATCH /private/webhooks/$WEBHOOK_ID operation. - * Note that you must explicitly start the operation after setup. + * Note that you must explicitly start the operation after + * possibly setting options. * * @param ctx the context * @param url base URL of the merchant backend @@ -41,8 +99,6 @@ struct TALER_MERCHANT_PatchPrivateWebhookHandle; * @param event_type new event type * @param url_template new notification URL template * @param http_method new HTTP method - * @param header_template new header template - * @param body_template new body template * @return handle to operation, NULL on error */ struct TALER_MERCHANT_PatchPrivateWebhookHandle * @@ -52,9 +108,94 @@ TALER_MERCHANT_patch_private_webhook_create ( const char *webhook_id, const char *event_type, const char *url_template, - const char *http_method, - const char *header_template, - const char *body_template); + const char *http_method); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PatchPrivateWebhookOptionValue + */ +#define TALER_MERCHANT_patch_private_webhook_option_end_() \ + (const struct TALER_MERCHANT_PatchPrivateWebhookOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_END \ + } + +/** + * Set header template. + * + * @param ht header template string to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateWebhookOptionValue + */ +#define TALER_MERCHANT_patch_private_webhook_option_header_template(ht) \ + (const struct TALER_MERCHANT_PatchPrivateWebhookOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_HEADER_TEMPLATE, \ + .details.header_template = (ht) \ + } + +/** + * Set body template. + * + * @param bt body template string to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateWebhookOptionValue + */ +#define TALER_MERCHANT_patch_private_webhook_option_body_template(bt) \ + (const struct TALER_MERCHANT_PatchPrivateWebhookOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_BODY_TEMPLATE, \ + .details.body_template = (bt) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param wph the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_webhook_set_options_ ( + struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateWebhookOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_patch_private_webhook_set_options ( + * wph, + * TALER_MERCHANT_patch_private_webhook_option_header_template ( + * "Content-Type: application/json")); + * + * @param wph the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_patch_private_webhook_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_private_webhook_set_options(wph,...) \ + TALER_MERCHANT_patch_private_webhook_set_options_ ( \ + wph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchPrivateWebhookOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_private_webhook_option_end_ () } \ + )) /** diff --git a/src/include/taler/taler-merchant/post-management-instances.h b/src/include/taler/taler-merchant/post-management-instances.h @@ -26,6 +26,140 @@ /** + * Possible options we can set for the POST /management/instances request. + */ +enum TALER_MERCHANT_PostManagementInstancesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_END = 0, + + /** + * Set the default pay delay. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY, + + /** + * Set the default refund delay. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY, + + /** + * Set the default wire transfer delay. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY, + + /** + * Set the default wire transfer rounding interval. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL, + + /** + * Set the email address. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_EMAIL, + + /** + * Set the phone number. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER, + + /** + * Set the website URL. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_WEBSITE, + + /** + * Set the logo. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_LOGO, + + /** + * Set the authentication password. + */ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_AUTH_PASSWORD + +}; + + +/** + * Value for an option for the POST /management/instances request. + */ +struct TALER_MERCHANT_PostManagementInstancesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostManagementInstancesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY. + */ + struct GNUNET_TIME_Relative default_pay_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY. + */ + struct GNUNET_TIME_Relative default_refund_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY. + */ + struct GNUNET_TIME_Relative default_wire_transfer_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL. + */ + enum GNUNET_TIME_RounderInterval default_wire_transfer_rounding_interval; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_EMAIL. + */ + const char *email; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER. + */ + const char *phone_number; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_WEBSITE. + */ + const char *website; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_LOGO. + */ + const char *logo; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_AUTH_PASSWORD. + */ + const char *auth_password; + + } details; + +}; + + +/** * Handle for a POST /management/instances request. */ struct TALER_MERCHANT_PostManagementInstancesHandle; @@ -68,10 +202,6 @@ struct TALER_MERCHANT_PostManagementInstancesResponse * @param address address (JSON) * @param jurisdiction jurisdiction (JSON) * @param use_stefan whether to use the STEFAN curve for fee calculations - * @param default_wire_transfer_delay default delay for wire transfers - * @param default_pay_delay default payment deadline - * @param default_refund_delay default refund deadline - * @param auth_password authentication password for the new instance, or NULL * @return handle to operation */ struct TALER_MERCHANT_PostManagementInstancesHandle * @@ -82,11 +212,193 @@ TALER_MERCHANT_post_management_instances_create ( const char *name, const json_t *address, const json_t *jurisdiction, - bool use_stefan, - struct GNUNET_TIME_Relative default_wire_transfer_delay, - struct GNUNET_TIME_Relative default_pay_delay, - struct GNUNET_TIME_Relative default_refund_delay, - const char *auth_password); + bool use_stefan); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PostManagementInstancesOptionValue + */ +#define TALER_MERCHANT_post_management_instances_option_end_() \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_END \ + } + +/** + * Set default pay delay. + * + * @param d delay to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_default_pay_delay(d) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY, \ + .details.default_pay_delay = (d) \ + } + +/** + * Set default refund delay. + * + * @param d delay to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_default_refund_delay(d) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY, \ + .details.default_refund_delay = (d) \ + } + +/** + * Set default wire transfer delay. + * + * @param d delay to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_default_wire_transfer_delay(d) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY, \ + .details.default_wire_transfer_delay = (d) \ + } + +/** + * Set default wire transfer rounding interval. + * + * @param ri rounding interval to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_default_wire_transfer_rounding_interval(ri) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL, \ + .details.default_wire_transfer_rounding_interval = (ri) \ + } + +/** + * Set email address. + * + * @param e email to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_email(e) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_EMAIL, \ + .details.email = (e) \ + } + +/** + * Set phone number. + * + * @param p phone number to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_phone_number(p) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER, \ + .details.phone_number = (p) \ + } + +/** + * Set website URL. + * + * @param w website to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_website(w) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_WEBSITE, \ + .details.website = (w) \ + } + +/** + * Set logo. + * + * @param l logo to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_logo(l) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_LOGO, \ + .details.logo = (l) \ + } + +/** + * Set authentication password. + * + * @param pw password to set + * @return representation of the option + */ +#define TALER_MERCHANT_post_management_instances_option_auth_password(pw) \ + (const struct TALER_MERCHANT_PostManagementInstancesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_AUTH_PASSWORD, \ + .details.auth_password = (pw) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param pmih the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_management_instances_set_options_ ( + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, + unsigned int num_options, + const struct TALER_MERCHANT_PostManagementInstancesOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_post_management_instances_set_options ( + * pmih, + * TALER_MERCHANT_post_management_instances_option_email ( + * "foo@example.com")); + * + * @param pmih the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_post_management_instances_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_post_management_instances_set_options(pmih,...) \ + TALER_MERCHANT_post_management_instances_set_options_ ( \ + pmih, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostManagementInstancesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_management_instances_option_end_ () \ + } \ + )) #ifndef TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-paid.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-paid.h @@ -88,6 +88,32 @@ struct TALER_MERCHANT_PostOrdersPaidResponse */ struct TALER_MERCHANT_HttpResponse hr; + /** + * Response details depending on HTTP status. + */ + union + { + + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + + /** + * POS confirmation string, or NULL if not available. + */ + const char *pos_confirmation; + + /** + * True if the order has been refunded. + */ + bool refunded; + + } ok; + + } details; + }; diff --git a/src/include/taler/taler-merchant/post-private-accounts.h b/src/include/taler/taler-merchant/post-private-accounts.h @@ -43,7 +43,12 @@ enum TALER_MERCHANT_PostPrivateAccountsOption /** * Credentials for the credit facade (JSON). */ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS, + + /** + * Extra wire subject metadata (restricted text). + */ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_EXTRA_WIRE_SUBJECT_METADATA }; @@ -77,6 +82,12 @@ struct TALER_MERCHANT_PostPrivateAccountsOptionValue */ const json_t *credit_facade_credentials; + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_EXTRA_WIRE_SUBJECT_METADATA. + */ + const char *extra_wire_subject_metadata; + } details; }; @@ -172,6 +183,20 @@ struct TALER_MERCHANT_PostPrivateAccountsResponse .details.credit_facade_credentials = (c) \ } +/** + * Set extra wire subject metadata. + * + * @param m extra wire subject metadata (JSON) + * @return representation of the option as a struct TALER_MERCHANT_PostPrivateAccountsOptionValue + */ +#define TALER_MERCHANT_post_private_accounts_option_extra_wire_subject_metadata(m) \ + (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_EXTRA_WIRE_SUBJECT_METADATA, \ + .details.extra_wire_subject_metadata = (m) \ + } + /** * Set the requested options for the operation. diff --git a/src/include/taler/taler-merchant/post-private-otp-devices.h b/src/include/taler/taler-merchant/post-private-otp-devices.h @@ -46,6 +46,52 @@ struct TALER_MERCHANT_PostPrivateOtpDevicesResponse /** + * Possible options we can set for the POST /private/otp-devices request. + */ +enum TALER_MERCHANT_PostPrivateOtpDevicesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_END = 0, + + /** + * Set the initial OTP counter value (for HOTP). + */ + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_OTP_CTR + +}; + + +/** + * Value for an option for the POST /private/otp-devices request. + */ +struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateOtpDevicesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_OTP_CTR. + */ + uint64_t otp_ctr; + + } details; + +}; + + +/** * Set up POST /private/otp-devices operation. * Note that you must explicitly start the operation after * possibly setting options. @@ -56,7 +102,6 @@ struct TALER_MERCHANT_PostPrivateOtpDevicesResponse * @param otp_device_description human-readable description * @param otp_key base32-encoded OTP secret key * @param otp_algorithm OTP algorithm to use - * @param otp_ctr initial counter value (for HOTP) * @return handle to operation */ struct TALER_MERCHANT_PostPrivateOtpDevicesHandle * @@ -66,8 +111,80 @@ TALER_MERCHANT_post_private_otp_devices_create ( const char *otp_device_id, const char *otp_device_description, const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm otp_algorithm, - uint64_t otp_ctr); + enum TALER_MerchantConfirmationAlgorithm otp_algorithm); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue + */ +#define TALER_MERCHANT_post_private_otp_devices_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_END \ + } + +/** + * Set the initial counter value (for HOTP). + * + * @param c the counter value + * @return representation of the option as a struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue + */ +#define TALER_MERCHANT_post_private_otp_devices_option_otp_ctr(c) \ + (const struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_OTP_CTR, \ + .details.otp_ctr = (c) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param ppoh the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_otp_devices_set_options_ ( + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_post_private_otp_devices_set_options ( + * ppoh, + * TALER_MERCHANT_post_private_otp_devices_option_otp_ctr (42)); + * + * @param ppoh the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_post_private_otp_devices_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_post_private_otp_devices_set_options(ppoh,...) \ + TALER_MERCHANT_post_private_otp_devices_set_options_ ( \ + ppoh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_otp_devices_option_end_ () \ + } \ + )) #ifndef TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE diff --git a/src/include/taler/taler-merchant/post-private-products.h b/src/include/taler/taler-merchant/post-private-products.h @@ -66,9 +66,14 @@ enum TALER_MERCHANT_PostPrivateProductsOption TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES, /** - * Additional unit prices. + * Value and fractional part of total stock. */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES, + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK, + + /** + * Value part of total stock (-1 for unlimited). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_VAL, /** * Fractional part of total stock. @@ -83,7 +88,32 @@ enum TALER_MERCHANT_PostPrivateProductsOption /** * Precision level for fractions. */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL, + + /** + * Explicit product name (distinct from description). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_NAME, + + /** + * Product image (base64-encoded data URL). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_IMAGE, + + /** + * Product group ID. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_GROUP_ID, + + /** + * Money pot ID. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MONEY_POT_ID, + + /** + * Whether the price is net (before tax). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRICE_IS_NET }; @@ -147,19 +177,23 @@ struct TALER_MERCHANT_PostPrivateProductsOptionValue /** * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES. + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK. */ struct { - const struct TALER_Amount *prices; - size_t len; - } unit_prices; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC. - */ - uint32_t total_stock_frac; + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_VAL. + * -1 for infinite stock. + */ + int64_t val; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC. + */ + uint32_t frac; + } total_stock; /** * Value if @e option is @@ -173,6 +207,36 @@ struct TALER_MERCHANT_PostPrivateProductsOptionValue */ uint32_t unit_precision_level; + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_NAME. + */ + const char *product_name; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_IMAGE. + */ + const char *image; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_GROUP_ID. + */ + uint64_t product_group_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MONEY_POT_ID. + */ + uint64_t money_pot_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRICE_IS_NET. + */ + bool price_is_net; + } details; }; @@ -290,31 +354,44 @@ struct TALER_MERCHANT_PostPrivateProductsResponse } /** - * Set additional unit prices. + * Set fractional part of total stock. * - * @param p array of unit prices - * @param l number of prices + * @param f fractional part * @return representation of the option */ -#define TALER_MERCHANT_post_private_products_option_unit_prices(p,l) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES, \ - .details.unit_prices = { .prices = (p), .len = (l) } \ +#define TALER_MERCHANT_post_private_products_option_total_stock_frac(f) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC, \ + .details.total_stock.frac = (f) \ } /** * Set fractional part of total stock. * - * @param f fractional part + * @param s total stock amount * @return representation of the option */ -#define TALER_MERCHANT_post_private_products_option_total_stock_frac(f) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC \ - , \ - .details.total_stock_frac = (f) \ +#define TALER_MERCHANT_post_private_products_option_total_stock_val(s) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_VAL, \ + .details.total_stock.val = (s) \ + } + +/** + * Set stock. + * + * @param s stock value + * @param f fractional stock + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_total_stock(s,f) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK, \ + .details.total_stock.val = (s), \ + .details.total_stock.frac = (f) \ } /** @@ -347,6 +424,75 @@ struct TALER_MERCHANT_PostPrivateProductsResponse /** + * Set explicit product name (distinct from description). + * + * @param n product name string + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_product_name(n) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_NAME, \ + .details.product_name = (n) \ + } + +/** + * Set product image (base64-encoded data URL). + * + * @param i image string + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_image(i) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_IMAGE, \ + .details.image = (i) \ + } + +/** + * Set product group ID. + * + * @param g product group ID + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_product_group_id(g) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_GROUP_ID, \ + .details.product_group_id = (g) \ + } + +/** + * Set money pot ID. + * + * @param m money pot ID + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_money_pot_id(m) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MONEY_POT_ID, \ + .details.money_pot_id = (m) \ + } + +/** + * Set whether the price is net (before tax). + * + * @param b true if price is net + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_price_is_net(b) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRICE_IS_NET, \ + .details.price_is_net = (b) \ + } + + +/** * Set the requested options for the operation. * * @param ppph the request to set the options for @@ -392,8 +538,8 @@ TALER_MERCHANT_post_private_products_set_options_ ( * @param description human-readable product description * @param unit unit of measurement * @param price unit price - * @param image base64-encoded image, or empty string - * @param total_stock total stock (-1 for unlimited) + * @param num_prices length of the @e prices array + * @param prices new unit prices * @return handle to operation */ struct TALER_MERCHANT_PostPrivateProductsHandle * @@ -403,9 +549,8 @@ TALER_MERCHANT_post_private_products_create ( const char *product_id, const char *description, const char *unit, - const struct TALER_Amount *price, - const char *image, - int64_t total_stock); + unsigned int num_prices, + const struct TALER_Amount prices[static num_prices]); #ifndef TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE diff --git a/src/include/taler/taler-merchant/post-private-templates.h b/src/include/taler/taler-merchant/post-private-templates.h @@ -38,7 +38,12 @@ enum TALER_MERCHANT_PostPrivateTemplatesOption /** * OTP device ID to associate with the template. */ - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID, + + /** + * Editable defaults (JSON object) for the template. + */ + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_EDITABLE_DEFAULTS }; @@ -66,6 +71,12 @@ struct TALER_MERCHANT_PostPrivateTemplatesOptionValue */ const char *otp_id; + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_EDITABLE_DEFAULTS. + */ + const json_t *editable_defaults; + } details; }; @@ -117,6 +128,21 @@ struct TALER_MERCHANT_PostPrivateTemplatesResponse /** + * Set editable defaults. + * + * @param ed editable defaults (JSON object) + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_templates_option_editable_defaults(ed) \ + (const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_EDITABLE_DEFAULTS, \ + .details.editable_defaults = (ed) \ + } + + +/** * Set the requested options for the operation. * * @param ppth the request to set the options for diff --git a/src/include/taler/taler-merchant/post-private-token.h b/src/include/taler/taler-merchant/post-private-token.h @@ -32,6 +32,74 @@ struct TALER_MERCHANT_PostPrivateTokenHandle; /** + * Possible options for the POST /private/token request. + */ +enum TALER_MERCHANT_PostPrivateTokenOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_END = 0, + + /** + * Duration for the token validity. + */ + TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DURATION, + + /** + * Whether the token may be refreshed. + */ + TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_REFRESHABLE, + + /** + * Description for the token. + */ + TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DESCRIPTION + +}; + + +/** + * Value for an option for the POST /private/token request. + */ +struct TALER_MERCHANT_PostPrivateTokenOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateTokenOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DURATION. + */ + struct GNUNET_TIME_Relative duration; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_REFRESHABLE. + */ + bool refreshable; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DESCRIPTION. + */ + const char *description; + + } details; + +}; + + +/** * Response details for a POST /private/token request. */ struct TALER_MERCHANT_PostPrivateTokenResponse @@ -47,16 +115,132 @@ struct TALER_MERCHANT_PostPrivateTokenResponse */ union { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + + /** + * The access token (RFC 8959 secret-token: URI). + */ + const char *access_token; + + /** + * The scope of the token. + */ + const char *scope; + + /** + * Whether the token may be refreshed. + */ + bool refreshable; + + /** + * When the token expires. + */ + struct GNUNET_TIME_Timestamp expiration; + + } ok; + /** * Details on #MHD_HTTP_ACCEPTED. */ struct TALER_MERCHANT_MfaChallengeResponse accepted; + } details; }; /** + * Terminate the list of the options. + * + * @return the terminating object + */ +#define TALER_MERCHANT_post_private_token_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateTokenOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_END \ + } + +/** + * Set duration for token validity. + * + * @param d the duration + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_token_option_duration(d) \ + (const struct TALER_MERCHANT_PostPrivateTokenOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DURATION, \ + .details.duration = (d) \ + } + +/** + * Set whether token is refreshable. + * + * @param r true if token may be refreshed + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_token_option_refreshable(r) \ + (const struct TALER_MERCHANT_PostPrivateTokenOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_REFRESHABLE, \ + .details.refreshable = (r) \ + } + +/** + * Set description for the token. + * + * @param d description string + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_token_option_description(d) \ + (const struct TALER_MERCHANT_PostPrivateTokenOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DESCRIPTION, \ + .details.description = (d) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ppth the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_token_set_options_ ( + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateTokenOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param ppth the request to set the options for + * @param ... the list of the options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_post_private_token_set_options(ppth,...) \ + TALER_MERCHANT_post_private_token_set_options_ ( \ + ppth, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateTokenOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_token_option_end_ () } \ + )) + + +/** * Set up POST /private/token operation. * Note that you must explicitly start the operation after * possibly setting options. @@ -65,8 +249,6 @@ struct TALER_MERCHANT_PostPrivateTokenResponse * @param url base URL of the merchant backend * @param instance_id identifier of the instance * @param scope scope for the token - * @param duration how long the token should be valid - * @param refreshable whether the token may be refreshed * @return handle to operation */ struct TALER_MERCHANT_PostPrivateTokenHandle * @@ -74,9 +256,7 @@ TALER_MERCHANT_post_private_token_create ( struct GNUNET_CURL_Context *ctx, const char *url, const char *instance_id, - const char *scope, - struct GNUNET_TIME_Relative duration, - bool refreshable); + const char *scope); #ifndef TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE diff --git a/src/include/taler/taler-merchant/post-private-units.h b/src/include/taler/taler-merchant/post-private-units.h @@ -43,7 +43,25 @@ enum TALER_MERCHANT_PostPrivateUnitsOption /** * Internationalized short names (JSON). */ - TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N, + + /** + * Whether fractional quantities are allowed (bool). + * Default: false. + */ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ALLOW_FRACTION, + + /** + * Precision level for fractional quantities (uint32_t). + * Default: 0. + */ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_PRECISION_LEVEL, + + /** + * Whether the unit is active (bool). + * Default: true. + */ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ACTIVE }; @@ -77,6 +95,24 @@ struct TALER_MERCHANT_PostPrivateUnitsOptionValue */ const json_t *unit_name_short_i18n; + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ALLOW_FRACTION. + */ + bool unit_allow_fraction; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_PRECISION_LEVEL. + */ + uint32_t unit_precision_level; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ACTIVE. + */ + bool unit_active; + } details; }; @@ -143,6 +179,49 @@ struct TALER_MERCHANT_PostPrivateUnitsResponse /** + * Set whether fractional quantities are allowed. + * + * @param v true to allow fractions + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_units_option_unit_allow_fraction(v) \ + (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ALLOW_FRACTION, \ + .details.unit_allow_fraction = (v) \ + } + +/** + * Set the precision level for fractional quantities. + * + * @param v precision level + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_units_option_unit_precision_level(v) \ + (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_PRECISION_LEVEL, \ + .details.unit_precision_level = (v) \ + } + +/** + * Set whether the unit is active. + * + * @param v true if active + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_units_option_unit_active(v) \ + (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ACTIVE, \ + .details.unit_active = (v) \ + } + + +/** * Set the requested options for the operation. * * @param ppuh the request to set the options for @@ -187,9 +266,6 @@ TALER_MERCHANT_post_private_units_set_options_ ( * @param unit_id identifier for the new unit * @param unit_name_long long human-readable name * @param unit_name_short short symbol for the unit - * @param unit_allow_fraction whether fractional quantities are allowed - * @param unit_precision_level precision level for fractional quantities - * @param unit_active whether the unit is active * @return handle to operation */ struct TALER_MERCHANT_PostPrivateUnitsHandle * @@ -198,10 +274,7 @@ TALER_MERCHANT_post_private_units_create ( const char *url, const char *unit_id, const char *unit_name_long, - const char *unit_name_short, - bool unit_allow_fraction, - uint32_t unit_precision_level, - bool unit_active); + const char *unit_name_short); #ifndef TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE diff --git a/src/include/taler/taler-merchant/post-private-webhooks.h b/src/include/taler/taler-merchant/post-private-webhooks.h @@ -26,6 +26,63 @@ /** + * Possible options we can set for the POST /private/webhooks request. + */ +enum TALER_MERCHANT_PostPrivateWebhooksOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_END = 0, + + /** + * Set the header template. + */ + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_HEADER_TEMPLATE, + + /** + * Set the body template. + */ + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_BODY_TEMPLATE + +}; + + +/** + * Value for an option for the POST /private/webhooks request. + */ +struct TALER_MERCHANT_PostPrivateWebhooksOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateWebhooksOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_HEADER_TEMPLATE. + */ + const char *header_template; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_BODY_TEMPLATE. + */ + const char *body_template; + + } details; + +}; + + +/** * Handle for a POST /private/webhooks request. */ struct TALER_MERCHANT_PostPrivateWebhooksHandle; @@ -56,8 +113,6 @@ struct TALER_MERCHANT_PostPrivateWebhooksResponse * @param event_type event type that triggers this webhook * @param notification_url URL to send notifications to * @param http_method HTTP method to use for notifications - * @param header_template template for HTTP request headers - * @param body_template template for the HTTP request body * @return handle to operation */ struct TALER_MERCHANT_PostPrivateWebhooksHandle * @@ -67,9 +122,94 @@ TALER_MERCHANT_post_private_webhooks_create ( const char *webhook_id, const char *event_type, const char *notification_url, - const char *http_method, - const char *header_template, // FIXME: use set_option - const char *body_template); // FIXME: use set_option + const char *http_method); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PostPrivateWebhooksOptionValue + */ +#define TALER_MERCHANT_post_private_webhooks_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateWebhooksOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_END \ + } + +/** + * Set header template. + * + * @param ht header template string to set + * @return representation of the option as a struct TALER_MERCHANT_PostPrivateWebhooksOptionValue + */ +#define TALER_MERCHANT_post_private_webhooks_option_header_template(ht) \ + (const struct TALER_MERCHANT_PostPrivateWebhooksOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_HEADER_TEMPLATE, \ + .details.header_template = (ht) \ + } + +/** + * Set body template. + * + * @param bt body template string to set + * @return representation of the option as a struct TALER_MERCHANT_PostPrivateWebhooksOptionValue + */ +#define TALER_MERCHANT_post_private_webhooks_option_body_template(bt) \ + (const struct TALER_MERCHANT_PostPrivateWebhooksOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_BODY_TEMPLATE, \ + .details.body_template = (bt) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param ppwh the request to set the options for + * @param num_options length of the @a options array + * @param options an array of options + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_webhooks_set_options_ ( + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateWebhooksOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * It should be used with helpers that create required options, for example: + * + * TALER_MERCHANT_post_private_webhooks_set_options ( + * ppwh, + * TALER_MERCHANT_post_private_webhooks_option_header_template ( + * "Content-Type: application/json")); + * + * @param ppwh the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_post_private_webhooks_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_post_private_webhooks_set_options(ppwh,...) \ + TALER_MERCHANT_post_private_webhooks_set_options_ ( \ + ppwh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateWebhooksOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_webhooks_option_end_ () } \ + )) #ifndef TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE diff --git a/src/lib/merchant_api_get-config.c b/src/lib/merchant_api_get-config.c @@ -134,6 +134,44 @@ handle_get_config_finished (void *cls, &pv), GNUNET_JSON_spec_string ("version", &cr.details.ok.ci.version), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("implementation", + &cr.details.ok.implementation), + NULL), + GNUNET_JSON_spec_bool ("have_self_provisioning", + &cr.details.ok.have_self_provisioning), + GNUNET_JSON_spec_bool ("have_donau", + &cr.details.ok.have_donau), + GNUNET_JSON_spec_string ("payment_target_types", + &cr.details.ok.payment_target_types), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("payment_target_regex", + &cr.details.ok.payment_target_regex), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_array_const ("mandatory_tan_channels", + &cr.details.ok.mandatory_tan_channels), + NULL), + GNUNET_JSON_spec_relative_time ("default_pay_delay", + &cr.details.ok.default_pay_delay), + GNUNET_JSON_spec_relative_time ("default_refund_delay", + &cr.details.ok.default_refund_delay), + GNUNET_JSON_spec_relative_time ("default_wire_transfer_delay", + &cr.details.ok.default_wire_transfer_delay), + GNUNET_JSON_spec_string ("default_persona", + &cr.details.ok.default_persona), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_array_const ("report_generators", + &cr.details.ok.report_generators), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("phone_regex", + &cr.details.ok.phone_regex), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_object_const ("spa_options", + &cr.details.ok.spa_options), + NULL), GNUNET_JSON_spec_end () }; diff --git a/src/lib/merchant_api_get-private-kyc.c b/src/lib/merchant_api_get-private-kyc.c @@ -105,6 +105,26 @@ struct TALER_MERCHANT_GetPrivateKycHandle * Instance ID for management mode, or NULL. */ char *instance_id; + + /** + * Long-poll status filter, or NULL. + */ + char *lp_status; + + /** + * Long-poll negated status filter, or NULL. + */ + char *lp_not_status; + + /** + * Long-poll ETag to suppress unchanged responses. + */ + struct GNUNET_ShortHashCode lp_not_etag; + + /** + * True if @e lp_not_etag was set. + */ + bool have_lp_not_etag; }; @@ -444,6 +464,23 @@ TALER_MERCHANT_get_private_kyc_set_options_ ( if (NULL != opt->details.instance_id) kyc->instance_id = GNUNET_strdup (opt->details.instance_id); break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_STATUS: + GNUNET_free (kyc->lp_status); + if (NULL != opt->details.lp_status) + kyc->lp_status = GNUNET_strdup (opt->details.lp_status); + break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_STATUS: + GNUNET_free (kyc->lp_not_status); + if (NULL != opt->details.lp_not_status) + kyc->lp_not_status = GNUNET_strdup (opt->details.lp_not_status); + break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_ETAG: + if (NULL != opt->details.lp_not_etag) + { + kyc->lp_not_etag = *opt->details.lp_not_etag; + kyc->have_lp_not_etag = true; + } + break; default: GNUNET_break (0); return GNUNET_NO; @@ -493,25 +530,48 @@ TALER_MERCHANT_get_private_kyc_start ( sizeof (timeout_ms), "%llu", tms); - kyc->url - = TALER_url_join ( - base_path, - "kyc", - "h_wire", - kyc->have_h_wire - ? GNUNET_h2s_full (&kyc->h_wire_val.hash) - : NULL, - "exchange_url", - kyc->exchange_url, - "timeout_ms", - GNUNET_TIME_relative_is_zero (kyc->timeout) - ? NULL - : timeout_ms, - "lpt", - TALER_EXCHANGE_KLPT_NONE == kyc->lpt - ? NULL - : lpt_str, - NULL); + { + char etag_str[sizeof (struct GNUNET_ShortHashCode) * 2 + 1]; + + if (kyc->have_lp_not_etag) + { + char *end; + + end = GNUNET_STRINGS_data_to_string ( + &kyc->lp_not_etag, + sizeof (kyc->lp_not_etag), + etag_str, + sizeof (etag_str) - 1); + *end = '\0'; + } + kyc->url + = TALER_url_join ( + base_path, + "kyc", + "h_wire", + kyc->have_h_wire + ? GNUNET_h2s_full (&kyc->h_wire_val.hash) + : NULL, + "exchange_url", + kyc->exchange_url, + "timeout_ms", + GNUNET_TIME_relative_is_zero (kyc->timeout) + ? NULL + : timeout_ms, + "lpt", + TALER_EXCHANGE_KLPT_NONE == kyc->lpt + ? NULL + : lpt_str, + "lp_status", + kyc->lp_status, + "lp_not_status", + kyc->lp_not_status, + "lp_not_etag", + kyc->have_lp_not_etag + ? etag_str + : NULL, + NULL); + } GNUNET_free (base_path); if (NULL == kyc->url) return TALER_EC_GENERIC_CONFIGURATION_INVALID; @@ -547,6 +607,8 @@ TALER_MERCHANT_get_private_kyc_cancel ( GNUNET_free (kyc->url); GNUNET_free (kyc->exchange_url); GNUNET_free (kyc->instance_id); + GNUNET_free (kyc->lp_status); + GNUNET_free (kyc->lp_not_status); GNUNET_free (kyc->base_url); GNUNET_free (kyc); } diff --git a/src/lib/merchant_api_get-private-otp-devices-DEVICE_ID.c b/src/lib/merchant_api_get-private-otp-devices-DEVICE_ID.c @@ -69,6 +69,26 @@ struct TALER_MERCHANT_GetPrivateOtpDeviceHandle * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Fake time for OTP code computation. + */ + struct GNUNET_TIME_Timestamp faketime; + + /** + * Price amount for OTP code computation. + */ + struct TALER_Amount price; + + /** + * True if @e faketime was explicitly set via options. + */ + bool have_faketime; + + /** + * True if @e price was explicitly set via options. + */ + bool have_price; }; @@ -176,6 +196,35 @@ TALER_MERCHANT_get_private_otp_device_create ( } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_otp_device_set_options_ ( + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateOtpDeviceOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_FAKETIME: + god->faketime = options[i].details.faketime; + god->have_faketime = true; + break; + case TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_OPTION_PRICE: + god->price = options[i].details.price; + god->have_price = true; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_get_private_otp_device_start ( struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, @@ -188,12 +237,31 @@ TALER_MERCHANT_get_private_otp_device_start ( god->cb_cls = cb_cls; { char *path; + char faketime_s[24]; GNUNET_asprintf (&path, "private/otp-devices/%s", god->otp_device_id); + if (god->have_faketime) + GNUNET_snprintf (faketime_s, + sizeof (faketime_s), + "%llu", + (unsigned long long) + GNUNET_TIME_timestamp_to_s (god->faketime)); god->url = TALER_url_join (god->base_url, path, + god->have_faketime + ? "faketime" + : NULL, + god->have_faketime + ? faketime_s + : NULL, + god->have_price + ? "price" + : NULL, + god->have_price + ? TALER_amount2s (&god->price) + : NULL, NULL); GNUNET_free (path); } diff --git a/src/lib/merchant_api_patch-management-instances-INSTANCE.c b/src/lib/merchant_api_patch-management-instances-INSTANCE.c @@ -100,19 +100,64 @@ struct TALER_MERCHANT_PatchManagementInstancesHandle bool use_stefan; /** - * Default wire transfer delay. + * Default wire transfer delay (optional). */ struct GNUNET_TIME_Relative default_wire_transfer_delay; /** - * Default payment deadline. + * Default payment deadline (optional). */ struct GNUNET_TIME_Relative default_pay_delay; /** - * Default refund deadline. + * Default refund deadline (optional). */ struct GNUNET_TIME_Relative default_refund_delay; + + /** + * Default wire transfer rounding interval (optional). + */ + enum GNUNET_TIME_RounderInterval default_wire_transfer_rounding_interval; + + /** + * Email address (optional). + */ + char *email; + + /** + * Phone number (optional). + */ + char *phone_number; + + /** + * Website URL (optional). + */ + char *website; + + /** + * Logo (optional). + */ + char *logo; + + /** + * Whether default_pay_delay was set. + */ + bool have_default_pay_delay; + + /** + * Whether default_refund_delay was set. + */ + bool have_default_refund_delay; + + /** + * Whether default_wire_transfer_delay was set. + */ + bool have_default_wire_transfer_delay; + + /** + * Whether default_wire_transfer_rounding_interval was set. + */ + bool have_default_wire_transfer_rounding_interval; }; @@ -196,10 +241,7 @@ TALER_MERCHANT_patch_management_instances_create ( const char *name, const json_t *address, const json_t *jurisdiction, - bool use_stefan, - struct GNUNET_TIME_Relative default_wire_transfer_delay, - struct GNUNET_TIME_Relative default_pay_delay, - struct GNUNET_TIME_Relative default_refund_delay) + bool use_stefan) { struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih; @@ -211,13 +253,63 @@ TALER_MERCHANT_patch_management_instances_create ( pmih->address = json_incref ((json_t *) address); pmih->jurisdiction = json_incref ((json_t *) jurisdiction); pmih->use_stefan = use_stefan; - pmih->default_wire_transfer_delay = default_wire_transfer_delay; - pmih->default_pay_delay = default_pay_delay; - pmih->default_refund_delay = default_refund_delay; return pmih; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_management_instances_set_options_ ( + struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih, + unsigned int num_options, + const struct TALER_MERCHANT_PatchManagementInstancesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY: + pmih->default_pay_delay = options[i].details.default_pay_delay; + pmih->have_default_pay_delay = true; + break; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY: + pmih->default_refund_delay = options[i].details.default_refund_delay; + pmih->have_default_refund_delay = true; + break; + case + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY: + pmih->default_wire_transfer_delay = + options[i].details.default_wire_transfer_delay; + pmih->have_default_wire_transfer_delay = true; + break; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL: + pmih->default_wire_transfer_rounding_interval = + options[i].details.default_wire_transfer_rounding_interval; + pmih->have_default_wire_transfer_rounding_interval = true; + break; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_EMAIL: + GNUNET_free (pmih->email); + pmih->email = GNUNET_strdup (options[i].details.email); + break; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER: + GNUNET_free (pmih->phone_number); + pmih->phone_number = GNUNET_strdup (options[i].details.phone_number); + break; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_WEBSITE: + GNUNET_free (pmih->website); + pmih->website = GNUNET_strdup (options[i].details.website); + break; + case TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_OPTION_LOGO: + GNUNET_free (pmih->logo); + pmih->logo = GNUNET_strdup (options[i].details.logo); + break; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_patch_management_instances_start ( struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih, @@ -251,15 +343,43 @@ TALER_MERCHANT_patch_management_instances_start ( pmih->jurisdiction), GNUNET_JSON_pack_bool ("use_stefan", pmih->use_stefan), - GNUNET_JSON_pack_time_rel ("default_wire_transfer_delay", - pmih->default_wire_transfer_delay), - GNUNET_JSON_pack_time_rel ("default_pay_delay", - pmih->default_pay_delay), - GNUNET_JSON_pack_time_rel ("default_refund_delay", - pmih->default_refund_delay), - GNUNET_JSON_pack_time_rounder_interval ( - "default_wire_transfer_rounding_interval", - GNUNET_TIME_RI_NONE) + GNUNET_JSON_pack_allow_null ( + pmih->have_default_wire_transfer_delay + ? GNUNET_JSON_pack_time_rel ("default_wire_transfer_delay", + pmih->default_wire_transfer_delay) + : GNUNET_JSON_pack_string ("default_wire_transfer_delay", + NULL)), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_pay_delay + ? GNUNET_JSON_pack_time_rel ("default_pay_delay", + pmih->default_pay_delay) + : GNUNET_JSON_pack_string ("default_pay_delay", + NULL)), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_refund_delay + ? GNUNET_JSON_pack_time_rel ("default_refund_delay", + pmih->default_refund_delay) + : GNUNET_JSON_pack_string ("default_refund_delay", + NULL)), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_wire_transfer_rounding_interval + ? GNUNET_JSON_pack_time_rounder_interval ( + "default_wire_transfer_rounding_interval", + pmih->default_wire_transfer_rounding_interval) + : GNUNET_JSON_pack_string ("default_wire_transfer_rounding_interval", + NULL)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("email", + pmih->email)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("phone_number", + pmih->phone_number)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("website", + pmih->website)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("logo", + pmih->logo)) ); eh = TALER_MERCHANT_curl_easy_get_ (pmih->url); if ( (NULL == eh) || @@ -304,6 +424,10 @@ TALER_MERCHANT_patch_management_instances_cancel ( json_decref (pmih->jurisdiction); GNUNET_free (pmih->instance_id); GNUNET_free (pmih->name); + GNUNET_free (pmih->email); + GNUNET_free (pmih->phone_number); + GNUNET_free (pmih->website); + GNUNET_free (pmih->logo); GNUNET_free (pmih->url); GNUNET_free (pmih->base_url); GNUNET_free (pmih); diff --git a/src/lib/merchant_api_patch-private-accounts-H_WIRE.c b/src/lib/merchant_api_patch-private-accounts-H_WIRE.c @@ -17,7 +17,7 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-accounts-H_WIRE-new.c + * @file merchant_api_patch-private-accounts-H_WIRE.c * @brief Implementation of the PATCH /private/accounts/$H_WIRE request * @author Christian Grothoff */ @@ -82,12 +82,17 @@ struct TALER_MERCHANT_PatchPrivateAccountHandle /** * Optional credit facade URL. */ - const char *credit_facade_url; + char *credit_facade_url; /** * Optional credit facade credentials (JSON). */ - const json_t *credit_facade_credentials; + json_t *credit_facade_credentials; + + /** + * Optional extra wire subject metadata (JSON). + */ + char*extra_wire_subject_metadata; }; @@ -193,11 +198,18 @@ TALER_MERCHANT_patch_private_account_set_options_ ( case TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_END: return GNUNET_OK; case TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL: - pah->credit_facade_url = options[i].details.credit_facade_url; + GNUNET_free (pah->credit_facade_url); + pah->credit_facade_url = GNUNET_strdup (options[i].details.credit_facade_url); break; case TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS: + json_decref (pah->credit_facade_credentials); pah->credit_facade_credentials - = options[i].details.credit_facade_credentials; + = json_incref ((json_t *) options[i].details.credit_facade_credentials); + break; + case TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_EXTRA_WIRE_SUBJECT_METADATA: + GNUNET_free (pah->extra_wire_subject_metadata); + pah->extra_wire_subject_metadata + = GNUNET_strdup (options[i].details.extra_wire_subject_metadata); break; default: GNUNET_break (0); @@ -245,7 +257,10 @@ TALER_MERCHANT_patch_private_account_start ( pah->credit_facade_url)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("credit_facade_credentials", - (json_t *) pah->credit_facade_credentials) + pah->credit_facade_credentials)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("extra_wire_subject_metadata", + pah->extra_wire_subject_metadata) )); eh = TALER_MERCHANT_curl_easy_get_ (pah->url); if ( (NULL == eh) || @@ -287,9 +302,12 @@ TALER_MERCHANT_patch_private_account_cancel ( } TALER_curl_easy_post_finished (&pah->post_ctx); GNUNET_free (pah->url); + GNUNET_free (pah->credit_facade_url); + json_decref (pah->credit_facade_credentials); + GNUNET_free (pah->extra_wire_subject_metadata); GNUNET_free (pah->base_url); GNUNET_free (pah); } -/* end of merchant_api_patch-private-accounts-H_WIRE-new.c */ +/* end of merchant_api_patch-private-accounts-H_WIRE.c */ diff --git a/src/lib/merchant_api_patch-private-otp-devices-DEVICE_ID.c b/src/lib/merchant_api_patch-private-otp-devices-DEVICE_ID.c @@ -98,6 +98,11 @@ struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle * Counter value (for HOTP). */ uint64_t otp_ctr; + + /** + * True if @e otp_ctr was explicitly set via options. + */ + bool have_otp_ctr; }; @@ -181,8 +186,7 @@ TALER_MERCHANT_patch_private_otp_device_create ( const char *otp_device_id, const char *otp_device_description, const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm mca, - uint64_t otp_ctr) + enum TALER_MerchantConfirmationAlgorithm mca) { struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh; @@ -194,11 +198,35 @@ TALER_MERCHANT_patch_private_otp_device_create ( if (NULL != otp_key) odh->otp_key = GNUNET_strdup (otp_key); odh->mca = mca; - odh->otp_ctr = otp_ctr; return odh; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_otp_device_set_options_ ( + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateOtpDeviceOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_OPTION_OTP_CTR: + odh->otp_ctr = options[i].details.otp_ctr; + odh->have_otp_ctr = true; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_patch_private_otp_device_start ( struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh, @@ -230,9 +258,13 @@ TALER_MERCHANT_patch_private_otp_device_start ( (uint32_t) odh->mca), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("otp_key", - odh->otp_key)), - GNUNET_JSON_pack_uint64 ("otp_ctr", - odh->otp_ctr)); + odh->otp_key))); + if (odh->have_otp_ctr) + { + json_object_set_new (req_obj, + "otp_ctr", + json_integer ((json_int_t) odh->otp_ctr)); + } eh = TALER_MERCHANT_curl_easy_get_ (odh->url); if ( (NULL == eh) || (GNUNET_OK != diff --git a/src/lib/merchant_api_patch-private-products-PRODUCT_ID.c b/src/lib/merchant_api_patch-private-products-PRODUCT_ID.c @@ -17,7 +17,7 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-products-PRODUCT_ID-new.c + * @file merchant_api_patch-private-products-PRODUCT_ID.c * @brief Implementation of the PATCH /private/products/$PRODUCT_ID request * @author Christian Grothoff */ @@ -95,14 +95,54 @@ struct TALER_MERCHANT_PatchPrivateProductHandle char *unit; /** - * New unit price. + * New base64-encoded image. */ - struct TALER_Amount price; + char *image; /** - * New base64-encoded image. + * Explicit product name (if different from description). */ - char *image; + char *product_name; + + /** + * Optional category IDs. + */ + uint64_t *cats; + + /** + * Product group ID. + */ + uint64_t product_group_id; + + /** + * Money pot ID. + */ + uint64_t money_pot_id; + + /** + * Whether money_pot_id has been set. + */ + bool have_money_pot_id; + + /** + * Whether the price is net (before tax). + */ + bool price_is_net; + + /** + * Whether price_is_net has been set. + */ + bool have_price_is_net; + + /** + * Whether product_group_id has been set. + */ + bool have_product_group_id; + + /** + * Number of category IDs. + */ + unsigned int num_cats; /** * New tax information (JSON array). @@ -130,9 +170,19 @@ struct TALER_MERCHANT_PatchPrivateProductHandle struct GNUNET_TIME_Timestamp next_restock; /** - * Optional unit prices array (for patch2 variant). + * Array of unit prices. + */ + struct TALER_Amount *unit_prices; + + /** + * Optional minimum age requirement. + */ + uint32_t minimum_age; + + /** + * Whether minimum_age has been set. */ - const struct TALER_Amount *unit_prices; + bool have_minimum_age; /** * Number of prices in @e unit_prices. @@ -150,7 +200,12 @@ struct TALER_MERCHANT_PatchPrivateProductHandle bool unit_allow_fraction; /** - * Whether unit_allow_fraction was explicitly set. + * Whether @e next_restock was explicitly set. + */ + bool have_next_restock; + + /** + * Whether @e unit_allow_fraction was explicitly set. */ bool have_unit_allow_fraction; @@ -160,7 +215,7 @@ struct TALER_MERCHANT_PatchPrivateProductHandle uint32_t unit_precision_level; /** - * Whether unit_precision_level was explicitly set. + * Whether @e unit_precision_level was explicitly set. */ bool have_unit_precision_level; }; @@ -251,15 +306,9 @@ TALER_MERCHANT_patch_private_product_create ( const char *url, const char *product_id, const char *description, - const json_t *description_i18n, const char *unit, - const struct TALER_Amount *price, - const char *image, - const json_t *taxes, - int64_t total_stock, - uint64_t total_lost, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock) + unsigned int num_prices, + const struct TALER_Amount prices[static num_prices]) { struct TALER_MERCHANT_PatchPrivateProductHandle *pph; @@ -268,22 +317,13 @@ TALER_MERCHANT_patch_private_product_create ( pph->base_url = GNUNET_strdup (url); pph->product_id = GNUNET_strdup (product_id); pph->description = GNUNET_strdup (description); - pph->description_i18n = json_incref ((json_t *) description_i18n); pph->unit = GNUNET_strdup (unit); - pph->price = *price; - pph->image = GNUNET_strdup (image); - pph->taxes = json_incref ((json_t *) taxes); - pph->total_stock = total_stock; - pph->total_lost = total_lost; - pph->address = json_incref ((json_t *) address); - pph->next_restock = next_restock; - /* Default: single price, no fractions */ - pph->unit_prices = NULL; - pph->unit_price_len = 0; - pph->total_stock_frac = 0; - pph->unit_allow_fraction = false; - pph->have_unit_allow_fraction = false; - pph->have_unit_precision_level = false; + pph->unit_price_len = num_prices; + pph->unit_prices = GNUNET_new_array (num_prices, + struct TALER_Amount); + memcpy (pph->unit_prices, + prices, + num_prices * sizeof (struct TALER_Amount)); return pph; } @@ -300,25 +340,80 @@ TALER_MERCHANT_patch_private_product_set_options_ ( { case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_END: return GNUNET_OK; - case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES: - pph->unit_prices = options[i].details.unit_prices.unit_prices; - pph->unit_price_len = options[i].details.unit_prices.unit_price_len; - break; case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC: - pph->total_stock_frac = options[i].details.total_stock_frac; - break; + pph->total_stock_frac = options[i].details.total_stock.frac; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_VAL: + pph->total_stock = options[i].details.total_stock.val; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK: + pph->total_stock = options[i].details.total_stock.val; + pph->total_stock_frac = options[i].details.total_stock.frac; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_LOST: + pph->total_lost = options[i].details.total_lost; + continue; case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION: pph->unit_allow_fraction = options[i].details.unit_allow_fraction; pph->have_unit_allow_fraction = true; - break; + continue; case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL: pph->unit_precision_level = options[i].details.unit_precision_level; pph->have_unit_precision_level = true; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_DESCRIPTION_I18N: + json_decref (pph->description_i18n); + pph->description_i18n = json_incref ( + (json_t *) options[i].details.description_i18n); + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TAXES: + json_decref (pph->taxes); + pph->taxes = json_incref ((json_t *) options[i].details.taxes); + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_ADDRESS: + json_decref (pph->address); + pph->address = json_incref ((json_t *) options[i].details.address); + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_NEXT_RESTOCK: + pph->next_restock = options[i].details.next_restock; + pph->have_next_restock = true; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MINIMUM_AGE: + pph->minimum_age = options[i].details.minimum_age; + pph->have_minimum_age = true; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_CATEGORIES: + pph->num_cats = options[i].details.categories.num; + GNUNET_free (pph->cats); + pph->cats = GNUNET_new_array (pph->num_cats, + uint64_t); + memcpy (pph->cats, + options[i].details.categories.cats, + pph->num_cats * sizeof (uint64_t)); + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_NAME: + GNUNET_free (pph->product_name); + pph->product_name = GNUNET_strdup (options[i].details.product_name); + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_IMAGE: + GNUNET_free (pph->image); + pph->image = GNUNET_strdup (options[i].details.image); + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRODUCT_GROUP_ID: + pph->product_group_id = options[i].details.product_group_id; + pph->have_product_group_id = true; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_MONEY_POT_ID: + pph->money_pot_id = options[i].details.money_pot_id; + pph->have_money_pot_id = true; + continue; + case TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_PRICE_IS_NET: + pph->price_is_net = options[i].details.price_is_net; + pph->have_price_is_net = true; + continue; } + GNUNET_break (0); + return GNUNET_SYSERR; } return GNUNET_OK; } @@ -332,8 +427,6 @@ TALER_MERCHANT_patch_private_product_start ( { json_t *req_obj; CURL *eh; - const struct TALER_Amount *prices; - size_t price_len; char unit_total_stock_buf[64]; pph->cb = cb; @@ -351,19 +444,6 @@ TALER_MERCHANT_patch_private_product_start ( } if (NULL == pph->url) return TALER_EC_GENERIC_CONFIGURATION_INVALID; - - /* Use explicit unit_prices if set, otherwise fall back to single price */ - if (NULL != pph->unit_prices) - { - prices = pph->unit_prices; - price_len = pph->unit_price_len; - } - else - { - prices = &pph->price; - price_len = 1; - } - TALER_MERCHANT_format_stock_string (pph->total_stock, pph->total_stock_frac, unit_total_stock_buf, @@ -375,22 +455,22 @@ TALER_MERCHANT_patch_private_product_start ( GNUNET_JSON_pack_string ("description", pph->description), GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) pph->description_i18n), + pph->description_i18n), GNUNET_JSON_pack_string ("unit", pph->unit), TALER_JSON_pack_amount_array ("unit_price", - price_len, - prices), + pph->unit_price_len, + pph->unit_prices), GNUNET_JSON_pack_string ("image", pph->image), GNUNET_JSON_pack_array_incref ("taxes", - (json_t *) pph->taxes), + pph->taxes), GNUNET_JSON_pack_string ("unit_total_stock", unit_total_stock_buf), GNUNET_JSON_pack_uint64 ("total_lost", pph->total_lost), GNUNET_JSON_pack_object_incref ("address", - (json_t *) pph->address), + pph->address), GNUNET_JSON_pack_timestamp ("next_restock", pph->next_restock)); if (pph->have_unit_allow_fraction && @@ -452,14 +532,17 @@ TALER_MERCHANT_patch_private_product_cancel ( json_decref (pph->description_i18n); json_decref (pph->taxes); json_decref (pph->address); + GNUNET_free (pph->cats); + GNUNET_free (pph->unit_prices); GNUNET_free (pph->url); GNUNET_free (pph->base_url); GNUNET_free (pph->product_id); GNUNET_free (pph->description); GNUNET_free (pph->unit); GNUNET_free (pph->image); + GNUNET_free (pph->product_name); GNUNET_free (pph); } -/* end of merchant_api_patch-private-products-PRODUCT_ID-new.c */ +/* end of merchant_api_patch-private-products-PRODUCT_ID.c */ diff --git a/src/lib/merchant_api_patch-private-templates-TEMPLATE_ID.c b/src/lib/merchant_api_patch-private-templates-TEMPLATE_ID.c @@ -93,6 +93,11 @@ struct TALER_MERCHANT_PatchPrivateTemplateHandle * New template contract (JSON). */ json_t *template_contract; + + /** + * Optional editable defaults (JSON object). + */ + json_t *editable_defaults; }; @@ -198,6 +203,31 @@ TALER_MERCHANT_patch_private_template_create ( } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_template_set_options_ ( + struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateTemplateOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_OPTION_EDITABLE_DEFAULTS: + tph->editable_defaults + = json_incref ((json_t *) options[i].details.editable_defaults); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_patch_private_template_start ( struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph, @@ -229,7 +259,10 @@ TALER_MERCHANT_patch_private_template_start ( GNUNET_JSON_pack_string ("otp_id", tph->otp_id)), GNUNET_JSON_pack_object_incref ("template_contract", - (json_t *) tph->template_contract)); + (json_t *) tph->template_contract), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("editable_defaults", + tph->editable_defaults))); eh = TALER_MERCHANT_curl_easy_get_ (tph->url); if ( (NULL == eh) || (GNUNET_OK != @@ -275,6 +308,7 @@ TALER_MERCHANT_patch_private_template_cancel ( GNUNET_free (tph->template_id); GNUNET_free (tph->template_description); GNUNET_free (tph->otp_id); + json_decref (tph->editable_defaults); GNUNET_free (tph); } diff --git a/src/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID.c b/src/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID.c @@ -17,7 +17,7 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c + * @file merchant_api_patch-private-webhooks-WEBHOOK_ID.c * @brief Implementation of the PATCH /private/webhooks/$WEBHOOK_ID request * @author Christian Grothoff */ @@ -95,12 +95,12 @@ struct TALER_MERCHANT_PatchPrivateWebhookHandle char *http_method; /** - * New header template. + * Optional new header template. */ char *header_template; /** - * New body template. + * Optional new body template. */ char *body_template; }; @@ -192,9 +192,7 @@ TALER_MERCHANT_patch_private_webhook_create ( const char *webhook_id, const char *event_type, const char *url_template, - const char *http_method, - const char *header_template, - const char *body_template) + const char *http_method) { struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph; @@ -205,12 +203,39 @@ TALER_MERCHANT_patch_private_webhook_create ( wph->event_type = GNUNET_strdup (event_type); wph->url_template = GNUNET_strdup (url_template); wph->http_method = GNUNET_strdup (http_method); - wph->header_template = GNUNET_strdup (header_template); - wph->body_template = GNUNET_strdup (body_template); return wph; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_webhook_set_options_ ( + struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateWebhookOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_HEADER_TEMPLATE: + GNUNET_free (wph->header_template); + wph->header_template = GNUNET_strdup (options[i].details.header_template); + break; + case TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_OPTION_BODY_TEMPLATE: + GNUNET_free (wph->body_template); + wph->body_template = GNUNET_strdup (options[i].details.body_template); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_patch_private_webhook_start ( struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph, @@ -242,10 +267,12 @@ TALER_MERCHANT_patch_private_webhook_start ( wph->url_template), GNUNET_JSON_pack_string ("http_method", wph->http_method), - GNUNET_JSON_pack_string ("header_template", - wph->header_template), - GNUNET_JSON_pack_string ("body_template", - wph->body_template)); + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("header_template", + wph->header_template)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("body_template", + wph->body_template))); eh = TALER_MERCHANT_curl_easy_get_ (wph->url); if ( (NULL == eh) || (GNUNET_OK != @@ -286,15 +313,15 @@ TALER_MERCHANT_patch_private_webhook_cancel ( } TALER_curl_easy_post_finished (&wph->post_ctx); GNUNET_free (wph->url); + GNUNET_free (wph->header_template); + GNUNET_free (wph->body_template); GNUNET_free (wph->base_url); GNUNET_free (wph->webhook_id); GNUNET_free (wph->event_type); GNUNET_free (wph->url_template); GNUNET_free (wph->http_method); - GNUNET_free (wph->header_template); - GNUNET_free (wph->body_template); GNUNET_free (wph); } -/* end of merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c */ +/* end of merchant_api_patch-private-webhooks-WEBHOOK_ID.c */ diff --git a/src/lib/merchant_api_post-management-instances.c b/src/lib/merchant_api_post-management-instances.c @@ -100,24 +100,69 @@ struct TALER_MERCHANT_PostManagementInstancesHandle bool use_stefan; /** - * Default wire transfer delay. + * Default wire transfer delay (optional, zero if not set). */ struct GNUNET_TIME_Relative default_wire_transfer_delay; /** - * Default payment deadline. + * Default payment deadline (optional, zero if not set). */ struct GNUNET_TIME_Relative default_pay_delay; /** - * Default refund deadline. + * Default refund deadline (optional, zero if not set). */ struct GNUNET_TIME_Relative default_refund_delay; /** + * Default wire transfer rounding interval (optional, zero if not set). + */ + enum GNUNET_TIME_RounderInterval default_wire_transfer_rounding_interval; + + /** * Authentication password (or NULL). */ char *auth_password; + + /** + * Optional email address. + */ + char *email; + + /** + * Optional phone number. + */ + char *phone_number; + + /** + * Optional website URL. + */ + char *website; + + /** + * Optional logo. + */ + char *logo; + + /** + * True if default_pay_delay was explicitly set via options. + */ + bool have_default_pay_delay; + + /** + * True if default_refund_delay was explicitly set via options. + */ + bool have_default_refund_delay; + + /** + * True if default_wire_transfer_delay was explicitly set via options. + */ + bool have_default_wire_transfer_delay; + + /** + * True if default_wire_transfer_rounding_interval was explicitly set via options. + */ + bool have_default_wire_transfer_rounding_interval; }; @@ -215,11 +260,7 @@ TALER_MERCHANT_post_management_instances_create ( const char *name, const json_t *address, const json_t *jurisdiction, - bool use_stefan, - struct GNUNET_TIME_Relative default_wire_transfer_delay, - struct GNUNET_TIME_Relative default_pay_delay, - struct GNUNET_TIME_Relative default_refund_delay, - const char *auth_password) + bool use_stefan) { struct TALER_MERCHANT_PostManagementInstancesHandle *pmih; @@ -231,15 +272,79 @@ TALER_MERCHANT_post_management_instances_create ( pmih->address = json_incref ((json_t *) address); pmih->jurisdiction = json_incref ((json_t *) jurisdiction); pmih->use_stefan = use_stefan; - pmih->default_wire_transfer_delay = default_wire_transfer_delay; - pmih->default_pay_delay = default_pay_delay; - pmih->default_refund_delay = default_refund_delay; - if (NULL != auth_password) - pmih->auth_password = GNUNET_strdup (auth_password); return pmih; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_management_instances_set_options_ ( + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, + unsigned int num_options, + const struct TALER_MERCHANT_PostManagementInstancesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_PAY_DELAY: + pmih->default_pay_delay = options[i].details.default_pay_delay; + pmih->have_default_pay_delay = true; + break; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_REFUND_DELAY: + pmih->default_refund_delay = options[i].details.default_refund_delay; + pmih->have_default_refund_delay = true; + break; + case + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_DELAY + : + pmih->default_wire_transfer_delay + = options[i].details.default_wire_transfer_delay; + pmih->have_default_wire_transfer_delay = true; + break; + case + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_DEFAULT_WIRE_TRANSFER_ROUNDING_INTERVAL + : + pmih->default_wire_transfer_rounding_interval + = options[i].details.default_wire_transfer_rounding_interval; + pmih->have_default_wire_transfer_rounding_interval = true; + break; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_EMAIL: + GNUNET_free (pmih->email); + if (NULL != options[i].details.email) + pmih->email = GNUNET_strdup (options[i].details.email); + break; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_PHONE_NUMBER: + GNUNET_free (pmih->phone_number); + if (NULL != options[i].details.phone_number) + pmih->phone_number = GNUNET_strdup (options[i].details.phone_number); + break; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_WEBSITE: + GNUNET_free (pmih->website); + if (NULL != options[i].details.website) + pmih->website = GNUNET_strdup (options[i].details.website); + break; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_LOGO: + GNUNET_free (pmih->logo); + if (NULL != options[i].details.logo) + pmih->logo = GNUNET_strdup (options[i].details.logo); + break; + case TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_OPTION_AUTH_PASSWORD: + GNUNET_free (pmih->auth_password); + if (NULL != options[i].details.auth_password) + pmih->auth_password = GNUNET_strdup ( + options[i].details.auth_password); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_post_management_instances_start ( struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, @@ -287,15 +392,44 @@ TALER_MERCHANT_post_management_instances_start ( pmih->jurisdiction), GNUNET_JSON_pack_bool ("use_stefan", pmih->use_stefan), - GNUNET_JSON_pack_time_rel ("default_wire_transfer_delay", - pmih->default_wire_transfer_delay), - GNUNET_JSON_pack_time_rel ("default_pay_delay", - pmih->default_pay_delay), - GNUNET_JSON_pack_time_rel ("default_refund_delay", - pmih->default_refund_delay), - GNUNET_JSON_pack_time_rounder_interval ( - "default_wire_transfer_rounding_interval", - GNUNET_TIME_RI_NONE), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_wire_transfer_delay + ? GNUNET_JSON_pack_time_rel ("default_wire_transfer_delay", + pmih->default_wire_transfer_delay) + : GNUNET_JSON_pack_string ("default_wire_transfer_delay", + NULL)), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_pay_delay + ? GNUNET_JSON_pack_time_rel ("default_pay_delay", + pmih->default_pay_delay) + : GNUNET_JSON_pack_string ("default_pay_delay", + NULL)), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_refund_delay + ? GNUNET_JSON_pack_time_rel ("default_refund_delay", + pmih->default_refund_delay) + : GNUNET_JSON_pack_string ("default_refund_delay", + NULL)), + GNUNET_JSON_pack_allow_null ( + pmih->have_default_wire_transfer_rounding_interval + ? GNUNET_JSON_pack_time_rounder_interval ( + "default_wire_transfer_rounding_interval", + pmih->default_wire_transfer_rounding_interval) + : GNUNET_JSON_pack_string ( + "default_wire_transfer_rounding_interval", + NULL)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("email", + pmih->email)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("phone_number", + pmih->phone_number)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("website", + pmih->website)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("logo", + pmih->logo)), GNUNET_JSON_pack_object_steal ("auth", auth_obj)); eh = TALER_MERCHANT_curl_easy_get_ (pmih->url); @@ -338,6 +472,10 @@ TALER_MERCHANT_post_management_instances_cancel ( GNUNET_free (pmih->instance_id); GNUNET_free (pmih->name); GNUNET_free (pmih->auth_password); + GNUNET_free (pmih->email); + GNUNET_free (pmih->phone_number); + GNUNET_free (pmih->website); + GNUNET_free (pmih->logo); GNUNET_free (pmih->url); GNUNET_free (pmih->base_url); GNUNET_free (pmih); diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-paid.c b/src/lib/merchant_api_post-orders-ORDER_ID-paid.c @@ -132,6 +132,27 @@ handle_paid_finished (void *cls, opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("pos_confirmation", + &opr.details.ok.pos_confirmation), + NULL), + GNUNET_JSON_spec_bool ("refunded", + &opr.details.ok.refunded), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json, + spec, + NULL, NULL)) + { + opr.hr.http_status = 0; + opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + } + } break; case MHD_HTTP_BAD_REQUEST: opr.hr.ec = TALER_JSON_get_error_code (json); diff --git a/src/lib/merchant_api_post-private-accounts.c b/src/lib/merchant_api_post-private-accounts.c @@ -17,7 +17,7 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-accounts-new.c + * @file merchant_api_post-private-accounts.c * @brief Implementation of the POST /private/accounts request * @author Christian Grothoff */ @@ -82,12 +82,17 @@ struct TALER_MERCHANT_PostPrivateAccountsHandle /** * Optional credit facade URL. */ - const char *credit_facade_url; + char *credit_facade_url; /** * Optional credit facade credentials (JSON). */ - const json_t *credit_facade_credentials; + json_t *credit_facade_credentials; + + /** + * Optional extra wire subject metadata (JSON). + */ + char *extra_wire_subject_metadata; }; @@ -223,11 +228,18 @@ TALER_MERCHANT_post_private_accounts_set_options_ ( case TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_END: return GNUNET_OK; case TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL: - pah->credit_facade_url = options[i].details.credit_facade_url; + GNUNET_free (pah->credit_facade_url); + pah->credit_facade_url = GNUNET_strdup (options[i].details.credit_facade_url); break; case TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS: + json_decref (pah->credit_facade_credentials); pah->credit_facade_credentials - = options[i].details.credit_facade_credentials; + = json_incref ((json_t *) options[i].details.credit_facade_credentials); + break; + case TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_EXTRA_WIRE_SUBJECT_METADATA: + GNUNET_free (pah->extra_wire_subject_metadata); + pah->extra_wire_subject_metadata + = GNUNET_strdup (options[i].details.extra_wire_subject_metadata); break; default: GNUNET_break (0); @@ -265,8 +277,11 @@ TALER_MERCHANT_post_private_accounts_start ( GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ( "credit_facade_credentials", - (json_t *) pah->credit_facade_credentials)) - ); + pah->credit_facade_credentials)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ( + "extra_wire_subject_metadata", + pah->extra_wire_subject_metadata))); eh = TALER_MERCHANT_curl_easy_get_ (pah->url); if ( (NULL == eh) || (GNUNET_OK != @@ -304,9 +319,12 @@ TALER_MERCHANT_post_private_accounts_cancel ( TALER_curl_easy_post_finished (&pah->post_ctx); GNUNET_free (pah->payto_uri.full_payto); GNUNET_free (pah->url); + GNUNET_free (pah->credit_facade_url); + json_decref (pah->credit_facade_credentials); + GNUNET_free (pah->extra_wire_subject_metadata); GNUNET_free (pah->base_url); GNUNET_free (pah); } -/* end of merchant_api_post-private-accounts-new.c */ +/* end of merchant_api_post-private-accounts.c */ diff --git a/src/lib/merchant_api_post-private-otp-devices.c b/src/lib/merchant_api_post-private-otp-devices.c @@ -98,6 +98,11 @@ struct TALER_MERCHANT_PostPrivateOtpDevicesHandle * Initial counter value (for HOTP). */ uint64_t otp_ctr; + + /** + * True if @e otp_ctr was explicitly set via options. + */ + bool have_otp_ctr; }; @@ -180,8 +185,7 @@ TALER_MERCHANT_post_private_otp_devices_create ( const char *otp_device_id, const char *otp_device_description, const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm otp_algorithm, - uint64_t otp_ctr) + enum TALER_MerchantConfirmationAlgorithm otp_algorithm) { struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh; @@ -193,11 +197,35 @@ TALER_MERCHANT_post_private_otp_devices_create ( if (NULL != otp_key) ppoh->otp_key = GNUNET_strdup (otp_key); ppoh->otp_algorithm = otp_algorithm; - ppoh->otp_ctr = otp_ctr; return ppoh; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_otp_devices_set_options_ ( + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateOtpDevicesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_OPTION_OTP_CTR: + ppoh->otp_ctr = options[i].details.otp_ctr; + ppoh->have_otp_ctr = true; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_post_private_otp_devices_start ( struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, diff --git a/src/lib/merchant_api_post-private-products.c b/src/lib/merchant_api_post-private-products.c @@ -90,14 +90,14 @@ struct TALER_MERCHANT_PostPrivateProductsHandle char *unit; /** - * Unit price. + * Product image (base64-encoded or empty), set via option. */ - struct TALER_Amount price; + char *image; /** - * Product image (base64-encoded or empty). + * Explicit product name (if different from description). */ - char *image; + char *product_name; /** * Total stock (-1 for unlimited). @@ -105,19 +105,49 @@ struct TALER_MERCHANT_PostPrivateProductsHandle int64_t total_stock; /** + * Product group ID. + */ + uint64_t product_group_id; + + /** + * Whether product_group_id has been set. + */ + bool have_product_group_id; + + /** + * Money pot ID. + */ + uint64_t money_pot_id; + + /** + * Whether money_pot_id has been set. + */ + bool have_money_pot_id; + + /** + * Whether the price is net (before tax). + */ + bool price_is_net; + + /** + * Whether price_is_net has been set. + */ + bool have_price_is_net; + + /** * Optional internationalized descriptions (JSON). */ - const json_t *description_i18n; + json_t *description_i18n; /** * Optional tax information (JSON array). */ - const json_t *taxes; + json_t *taxes; /** * Optional storage location (JSON). */ - const json_t *address; + json_t *address; /** * Optional expected restock time. @@ -142,7 +172,7 @@ struct TALER_MERCHANT_PostPrivateProductsHandle /** * Optional category IDs. */ - const uint64_t *cats; + uint64_t *cats; /** * Number of category IDs. @@ -150,12 +180,12 @@ struct TALER_MERCHANT_PostPrivateProductsHandle unsigned int num_cats; /** - * Optional additional unit prices. + * Array of unit prices. */ - const struct TALER_Amount *unit_prices; + struct TALER_Amount *unit_prices; /** - * Number of additional unit prices. + * Length of @e unit_prices array. */ size_t unit_prices_len; @@ -265,9 +295,8 @@ TALER_MERCHANT_post_private_products_create ( const char *product_id, const char *description, const char *unit, - const struct TALER_Amount *price, - const char *image, - int64_t total_stock) + unsigned int num_prices, + const struct TALER_Amount prices[static num_prices]) { struct TALER_MERCHANT_PostPrivateProductsHandle *ppph; @@ -277,9 +306,12 @@ TALER_MERCHANT_post_private_products_create ( ppph->product_id = GNUNET_strdup (product_id); ppph->description = GNUNET_strdup (description); ppph->unit = GNUNET_strdup (unit); - ppph->price = *price; - ppph->image = GNUNET_strdup (image); - ppph->total_stock = total_stock; + ppph->unit_prices_len = num_prices; + ppph->unit_prices = GNUNET_new_array (num_prices, + struct TALER_Amount); + memcpy (ppph->unit_prices, + prices, + num_prices * sizeof (struct TALER_Amount)); return ppph; } @@ -297,45 +329,76 @@ TALER_MERCHANT_post_private_products_set_options_ ( case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_END: return GNUNET_OK; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N: - ppph->description_i18n = options[i].details.description_i18n; - break; + json_decref (ppph->description_i18n); + ppph->description_i18n = json_incref ((json_t *) options[i].details. + description_i18n); + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES: - ppph->taxes = options[i].details.taxes; - break; + json_decref (ppph->taxes); + ppph->taxes = json_incref ((json_t *) options[i].details.taxes); + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS: - ppph->address = options[i].details.address; - break; + json_decref (ppph->address); + ppph->address = json_incref ((json_t *) options[i].details.address); + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK: ppph->next_restock = options[i].details.next_restock; ppph->have_next_restock = true; - break; + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE: ppph->minimum_age = options[i].details.minimum_age; ppph->have_minimum_age = true; - break; + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES: ppph->num_cats = options[i].details.categories.num; - ppph->cats = options[i].details.categories.cats; - break; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES: - ppph->unit_prices = options[i].details.unit_prices.prices; - ppph->unit_prices_len = options[i].details.unit_prices.len; - break; + GNUNET_free (ppph->cats); + ppph->cats = GNUNET_new_array (ppph->num_cats, + uint64_t); + memcpy (ppph->cats, + options[i].details.categories.cats, + ppph->num_cats * sizeof (uint64_t)); + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC: - ppph->total_stock_frac = options[i].details.total_stock_frac; - break; + ppph->total_stock_frac = options[i].details.total_stock.frac; + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_VAL: + ppph->total_stock = options[i].details.total_stock.val; + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK: + ppph->total_stock_frac = options[i].details.total_stock.frac; + ppph->total_stock = options[i].details.total_stock.val; + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_ALLOW_FRACTION: ppph->unit_allow_fraction = options[i].details.unit_allow_fraction; ppph->have_unit_allow_fraction = true; - break; + continue; case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL: ppph->unit_precision_level = options[i].details.unit_precision_level; ppph->have_unit_precision_level = true; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_NAME: + GNUNET_free (ppph->product_name); + ppph->product_name = GNUNET_strdup (options[i].details.product_name); + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_IMAGE: + GNUNET_free (ppph->image); + ppph->image = GNUNET_strdup (options[i].details.image); + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRODUCT_GROUP_ID: + ppph->product_group_id = options[i].details.product_group_id; + ppph->have_product_group_id = true; + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MONEY_POT_ID: + ppph->money_pot_id = options[i].details.money_pot_id; + ppph->have_money_pot_id = true; + continue; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_PRICE_IS_NET: + ppph->price_is_net = options[i].details.price_is_net; + ppph->have_price_is_net = true; + continue; } + GNUNET_break (0); + return GNUNET_SYSERR; } return GNUNET_OK; } @@ -350,8 +413,6 @@ TALER_MERCHANT_post_private_products_start ( json_t *req_obj; json_t *categories; CURL *eh; - const struct TALER_Amount *unit_prices; - size_t unit_price_len; char unit_total_stock_buf[64]; ppph->cb = cb; @@ -381,46 +442,37 @@ TALER_MERCHANT_post_private_products_start ( json_integer (ppph->cats[i]))); } - if ( (NULL != ppph->unit_prices) && - (0 < ppph->unit_prices_len) ) - { - unit_prices = ppph->unit_prices; - unit_price_len = ppph->unit_prices_len; - } - else - { - unit_prices = &ppph->price; - unit_price_len = 1; - } - req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("product_id", ppph->product_id), GNUNET_JSON_pack_string ("product_name", - ppph->description), + (NULL != ppph->product_name) + ? ppph->product_name + : ppph->description), GNUNET_JSON_pack_string ("description", ppph->description), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) ppph->description_i18n)), + ppph->description_i18n)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_array_steal ("categories", categories)), GNUNET_JSON_pack_string ("unit", ppph->unit), TALER_JSON_pack_amount_array ("unit_price", - unit_price_len, - unit_prices), - GNUNET_JSON_pack_string ("image", - ppph->image), + ppph->unit_prices_len, + ppph->unit_prices), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("image", + ppph->image)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_array_incref ("taxes", - (json_t *) ppph->taxes)), + ppph->taxes)), GNUNET_JSON_pack_string ("unit_total_stock", unit_total_stock_buf), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("address", - (json_t *) ppph->address)), + ppph->address)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_timestamp ("next_restock", ppph->have_next_restock @@ -434,6 +486,30 @@ TALER_MERCHANT_post_private_products_start ( json_integer ( ppph->minimum_age))); } + if (ppph->have_product_group_id) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "product_group_id", + json_integer ( + ppph->product_group_id))); + } + if (ppph->have_money_pot_id) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "money_pot_id", + json_integer ( + ppph->money_pot_id))); + } + if (ppph->have_price_is_net) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "price_is_net", + json_boolean ( + ppph->price_is_net))); + } if (ppph->have_unit_allow_fraction && ppph->unit_allow_fraction) { @@ -485,10 +561,15 @@ TALER_MERCHANT_post_private_products_cancel ( ppph->job = NULL; } TALER_curl_easy_post_finished (&ppph->post_ctx); + json_decref (ppph->description_i18n); + json_decref (ppph->taxes); + json_decref (ppph->address); + GNUNET_free (ppph->cats); GNUNET_free (ppph->product_id); GNUNET_free (ppph->description); GNUNET_free (ppph->unit); GNUNET_free (ppph->image); + GNUNET_free (ppph->product_name); GNUNET_free (ppph->url); GNUNET_free (ppph->base_url); GNUNET_free (ppph); diff --git a/src/lib/merchant_api_post-private-templates.c b/src/lib/merchant_api_post-private-templates.c @@ -93,6 +93,11 @@ struct TALER_MERCHANT_PostPrivateTemplatesHandle * Optional OTP device ID. */ char *otp_id; + + /** + * Optional editable defaults (JSON object). + */ + json_t *editable_defaults; }; @@ -204,6 +209,10 @@ TALER_MERCHANT_post_private_templates_set_options_ ( case TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID: ppth->otp_id = GNUNET_strdup (options[i].details.otp_id); break; + case TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_EDITABLE_DEFAULTS: + ppth->editable_defaults + = json_incref ((json_t *) options[i].details.editable_defaults); + break; default: GNUNET_break (0); return GNUNET_SYSERR; @@ -238,7 +247,10 @@ TALER_MERCHANT_post_private_templates_start ( GNUNET_JSON_pack_string ("otp_id", ppth->otp_id)), GNUNET_JSON_pack_object_incref ("template_contract", - ppth->template_contract)); + ppth->template_contract), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("editable_defaults", + ppth->editable_defaults))); eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); if ( (NULL == eh) || (GNUNET_OK != @@ -278,6 +290,7 @@ TALER_MERCHANT_post_private_templates_cancel ( GNUNET_free (ppth->template_id); GNUNET_free (ppth->template_description); GNUNET_free (ppth->otp_id); + json_decref (ppth->editable_defaults); GNUNET_free (ppth->url); GNUNET_free (ppth->base_url); GNUNET_free (ppth); diff --git a/src/lib/merchant_api_post-private-token.c b/src/lib/merchant_api_post-private-token.c @@ -17,7 +17,7 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-token-new.c + * @file merchant_api_post-private-token.c * @brief Implementation of the POST /private/token request * @author Christian Grothoff */ @@ -90,9 +90,24 @@ struct TALER_MERCHANT_PostPrivateTokenHandle struct GNUNET_TIME_Relative duration; /** + * Whether @e duration was explicitly set via options. + */ + bool duration_set; + + /** * Whether the token may be refreshed. */ bool refreshable; + + /** + * Whether @e refreshable was explicitly set via options. + */ + bool refreshable_set; + + /** + * Description for the token (or NULL). + */ + const char *description; }; @@ -123,6 +138,31 @@ handle_post_token_finished (void *cls, switch (response_code) { case MHD_HTTP_OK: + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("access_token", + &ptr.details.ok.access_token), + GNUNET_JSON_spec_string ("scope", + &ptr.details.ok.scope), + GNUNET_JSON_spec_bool ("refreshable", + &ptr.details.ok.refreshable), + GNUNET_JSON_spec_timestamp ("expiration", + &ptr.details.ok.expiration), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json, + spec, + NULL, + NULL)) + { + GNUNET_break_op (0); + ptr.hr.http_status = 0; + ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + } + } break; case MHD_HTTP_BAD_REQUEST: ptr.hr.ec = TALER_JSON_get_error_code (json); @@ -166,9 +206,7 @@ TALER_MERCHANT_post_private_token_create ( struct GNUNET_CURL_Context *ctx, const char *url, const char *instance_id, - const char *scope, - struct GNUNET_TIME_Relative duration, - bool refreshable) + const char *scope) { struct TALER_MERCHANT_PostPrivateTokenHandle *ppth; @@ -178,12 +216,42 @@ TALER_MERCHANT_post_private_token_create ( if (NULL != instance_id) ppth->instance_id = GNUNET_strdup (instance_id); ppth->scope = GNUNET_strdup (scope); - ppth->duration = duration; - ppth->refreshable = refreshable; return ppth; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_token_set_options_ ( + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateTokenOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DURATION: + ppth->duration = options[i].details.duration; + ppth->duration_set = true; + break; + case TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_REFRESHABLE: + ppth->refreshable = options[i].details.refreshable; + ppth->refreshable_set = true; + break; + case TALER_MERCHANT_POST_PRIVATE_TOKEN_OPTION_DESCRIPTION: + ppth->description = options[i].details.description; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_post_private_token_start ( struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, @@ -216,12 +284,30 @@ TALER_MERCHANT_post_private_token_start ( if (NULL == ppth->url) return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_time_rel ("duration", - ppth->duration), - GNUNET_JSON_pack_bool ("refreshable", - ppth->refreshable), GNUNET_JSON_pack_string ("scope", ppth->scope)); + if (ppth->duration_set) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "duration", + GNUNET_JSON_from_time_rel ( + ppth->duration))); + } + if (ppth->refreshable_set) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "refreshable", + json_boolean (ppth->refreshable))); + } + if (NULL != ppth->description) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "description", + json_string (ppth->description))); + } eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); if ( (NULL == eh) || (GNUNET_OK != @@ -269,4 +355,4 @@ TALER_MERCHANT_post_private_token_cancel ( } -/* end of merchant_api_post-private-token-new.c */ +/* end of merchant_api_post-private-token.c */ diff --git a/src/lib/merchant_api_post-private-transfers.c b/src/lib/merchant_api_post-private-transfers.c @@ -134,6 +134,10 @@ handle_post_transfers_finished (void *cls, ptr.hr.ec = TALER_JSON_get_error_code (json); ptr.hr.hint = TALER_JSON_get_error_hint (json); break; + case MHD_HTTP_CONFLICT: + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_INTERNAL_SERVER_ERROR: ptr.hr.ec = TALER_JSON_get_error_code (json); ptr.hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/lib/merchant_api_post-private-units.c b/src/lib/merchant_api_post-private-units.c @@ -105,6 +105,21 @@ struct TALER_MERCHANT_PostPrivateUnitsHandle bool unit_active; /** + * Whether @e unit_allow_fraction was explicitly set via options. + */ + bool have_unit_allow_fraction; + + /** + * Whether @e unit_precision_level was explicitly set via options. + */ + bool have_unit_precision_level; + + /** + * Whether @e unit_active was explicitly set via options. + */ + bool have_unit_active; + + /** * Optional internationalized long names (JSON). */ json_t *unit_name_long_i18n; @@ -179,10 +194,7 @@ TALER_MERCHANT_post_private_units_create ( const char *url, const char *unit_id, const char *unit_name_long, - const char *unit_name_short, - bool unit_allow_fraction, - uint32_t unit_precision_level, - bool unit_active) + const char *unit_name_short) { struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh; @@ -192,9 +204,6 @@ TALER_MERCHANT_post_private_units_create ( ppuh->unit_id = GNUNET_strdup (unit_id); ppuh->unit_name_long = GNUNET_strdup (unit_name_long); ppuh->unit_name_short = GNUNET_strdup (unit_name_short); - ppuh->unit_allow_fraction = unit_allow_fraction; - ppuh->unit_precision_level = unit_precision_level; - ppuh->unit_active = unit_active; return ppuh; } @@ -219,6 +228,18 @@ TALER_MERCHANT_post_private_units_set_options_ ( ppuh->unit_name_short_i18n = json_incref ((json_t *) options[i].details.unit_name_short_i18n); break; + case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ALLOW_FRACTION: + ppuh->unit_allow_fraction = options[i].details.unit_allow_fraction; + ppuh->have_unit_allow_fraction = true; + break; + case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_PRECISION_LEVEL: + ppuh->unit_precision_level = options[i].details.unit_precision_level; + ppuh->have_unit_precision_level = true; + break; + case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_ACTIVE: + ppuh->unit_active = options[i].details.unit_active; + ppuh->have_unit_active = true; + break; default: GNUNET_break (0); return GNUNET_SYSERR; @@ -252,11 +273,17 @@ TALER_MERCHANT_post_private_units_start ( GNUNET_JSON_pack_string ("unit_name_short", ppuh->unit_name_short), GNUNET_JSON_pack_bool ("unit_allow_fraction", - ppuh->unit_allow_fraction), + ppuh->have_unit_allow_fraction + ? ppuh->unit_allow_fraction + : false), GNUNET_JSON_pack_uint64 ("unit_precision_level", - (uint64_t) ppuh->unit_precision_level), + ppuh->have_unit_precision_level + ? (uint64_t) ppuh->unit_precision_level + : 0), GNUNET_JSON_pack_bool ("unit_active", - ppuh->unit_active), + ppuh->have_unit_active + ? ppuh->unit_active + : true), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("unit_name_long_i18n", ppuh->unit_name_long_i18n)), diff --git a/src/lib/merchant_api_post-private-webhooks.c b/src/lib/merchant_api_post-private-webhooks.c @@ -95,14 +95,14 @@ struct TALER_MERCHANT_PostPrivateWebhooksHandle char *http_method; /** - * Template for HTTP request headers. + * Optional template for HTTP request headers. */ - char *header_template; + const char *header_template; /** - * Template for the HTTP request body. + * Optional template for the HTTP request body. */ - char *body_template; + const char *body_template; }; @@ -185,9 +185,7 @@ TALER_MERCHANT_post_private_webhooks_create ( const char *webhook_id, const char *event_type, const char *notification_url, - const char *http_method, - const char *header_template, - const char *body_template) + const char *http_method) { struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh; @@ -198,12 +196,37 @@ TALER_MERCHANT_post_private_webhooks_create ( ppwh->event_type = GNUNET_strdup (event_type); ppwh->notification_url = GNUNET_strdup (notification_url); ppwh->http_method = GNUNET_strdup (http_method); - ppwh->header_template = GNUNET_strdup (header_template); - ppwh->body_template = GNUNET_strdup (body_template); return ppwh; } +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_webhooks_set_options_ ( + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateWebhooksOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_HEADER_TEMPLATE: + ppwh->header_template = options[i].details.header_template; + break; + case TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_OPTION_BODY_TEMPLATE: + ppwh->body_template = options[i].details.body_template; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum TALER_ErrorCode TALER_MERCHANT_post_private_webhooks_start ( struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, @@ -229,10 +252,12 @@ TALER_MERCHANT_post_private_webhooks_start ( ppwh->notification_url), GNUNET_JSON_pack_string ("http_method", ppwh->http_method), - GNUNET_JSON_pack_string ("header_template", - ppwh->header_template), - GNUNET_JSON_pack_string ("body_template", - ppwh->body_template)); + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("header_template", + ppwh->header_template)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("body_template", + ppwh->body_template))); eh = TALER_MERCHANT_curl_easy_get_ (ppwh->url); if ( (NULL == eh) || (GNUNET_OK != @@ -272,8 +297,6 @@ TALER_MERCHANT_post_private_webhooks_cancel ( GNUNET_free (ppwh->event_type); GNUNET_free (ppwh->notification_url); GNUNET_free (ppwh->http_method); - GNUNET_free (ppwh->header_template); - GNUNET_free (ppwh->body_template); GNUNET_free (ppwh->url); GNUNET_free (ppwh->base_url); GNUNET_free (ppwh); diff --git a/src/testing/testing_api_cmd_instance_token.c b/src/testing/testing_api_cmd_instance_token.c @@ -105,11 +105,6 @@ token_instance_post_cb (void *cls, ptr) { struct TokenInstanceState *tis = cls; - const char *scope; - struct GNUNET_TIME_Timestamp duration; - bool refreshable; - const char *error_name; - unsigned int error_line; tis->itph = NULL; if (tis->http_status != ptr->hr.http_status) @@ -125,40 +120,9 @@ token_instance_post_cb (void *cls, switch (ptr->hr.http_status) { case MHD_HTTP_OK: - { - /* Get token */ - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string_copy ("access_token", - &tis->token), - GNUNET_JSON_spec_string ("scope", - &scope), - GNUNET_JSON_spec_bool ("refreshable", - &refreshable), - GNUNET_JSON_spec_timestamp ("expiration", - &duration), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (ptr->hr.reply, - spec, - &error_name, - &error_line)) - { - char *js; - - js = json_dumps (ptr->hr.reply, - JSON_INDENT (1)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Parser failed on %s:%u for input `%s'\n", - error_name, - error_line, - js); - free (js); - TALER_TESTING_FAIL (tis->is); - } - break; - } + if (NULL != ptr->details.ok.access_token) + tis->token = GNUNET_strdup (ptr->details.ok.access_token); + break; case MHD_HTTP_BAD_REQUEST: /* likely invalid auth value, we do not check client-side */ break; @@ -275,9 +239,14 @@ token_instance_run (void *cls, TALER_TESTING_interpreter_get_context (is), tis->merchant_url, tis->instance_id, - tis->scope, - tis->duration, - tis->refreshable); + tis->scope); + GNUNET_assert (GNUNET_OK == + TALER_MERCHANT_post_private_token_set_options ( + tis->itph, + TALER_MERCHANT_post_private_token_option_duration ( + tis->duration), + TALER_MERCHANT_post_private_token_option_refreshable ( + tis->refreshable))); { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_patch_instance.c b/src/testing/testing_api_cmd_patch_instance.c @@ -163,11 +163,18 @@ patch_instance_run (void *cls, pis->name, pis->address, pis->jurisdiction, - pis->use_stefan, - pis->default_wire_transfer_delay, - pis->default_pay_delay, - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, - 15)); + pis->use_stefan); + GNUNET_assert ( + GNUNET_OK == + TALER_MERCHANT_patch_management_instances_set_options ( + pis->iph, + TALER_MERCHANT_patch_management_instances_option_default_wire_transfer_delay ( + pis->default_wire_transfer_delay), + TALER_MERCHANT_patch_management_instances_option_default_pay_delay ( + pis->default_pay_delay), + TALER_MERCHANT_patch_management_instances_option_default_refund_delay ( + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, + 15)))); GNUNET_assert (NULL != pis->iph); { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_patch_otp_device.c b/src/testing/testing_api_cmd_patch_otp_device.c @@ -151,9 +151,12 @@ patch_otp_device_run (void *cls, pis->otp_device_id, pis->otp_device_description, pis->otp_key, - pis->otp_alg, - pis->otp_ctr); + pis->otp_alg); GNUNET_assert (NULL != pis->iph); + if (0 != pis->otp_ctr) + TALER_MERCHANT_patch_private_otp_device_set_options ( + pis->iph, + TALER_MERCHANT_patch_private_otp_device_option_otp_ctr (pis->otp_ctr)); { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_patch_product.c b/src/testing/testing_api_cmd_patch_product.c @@ -304,34 +304,25 @@ patch_product_run (void *cls, pis->merchant_url, pis->product_id, pis->description, - pis->description_i18n, pis->unit, - &pis->price, - pis->image, - pis->taxes, - pis->total_stock, - pis->total_lost, - pis->address, - pis->next_restock); + pis->unit_prices_len, + pis->unit_prices); + GNUNET_assert ( + GNUNET_OK == + TALER_MERCHANT_patch_private_product_set_options ( + pis->iph, + TALER_MERCHANT_patch_private_product_option_description_i18n (pis->description_i18n), + TALER_MERCHANT_patch_private_product_option_image (pis->image), + TALER_MERCHANT_patch_private_product_option_taxes (pis->taxes), + TALER_MERCHANT_patch_private_product_option_total_stock_val (pis->total_stock), + TALER_MERCHANT_patch_private_product_option_total_lost (pis->total_lost), + TALER_MERCHANT_patch_private_product_option_address (pis->address), + TALER_MERCHANT_patch_private_product_option_next_restock (pis->next_restock))); GNUNET_assert (NULL != pis->iph); if (pis->use_fractional) { - if (pis->use_unit_price_array) - { - TALER_MERCHANT_patch_private_product_set_options ( - pis->iph, - TALER_MERCHANT_patch_private_product_option_unit_prices ( - pis->unit_prices, - pis->unit_prices_len), - TALER_MERCHANT_patch_private_product_option_total_stock_frac ( - pis->total_stock_frac), - TALER_MERCHANT_patch_private_product_option_unit_allow_fraction ( - pis->unit_allow_fraction), - TALER_MERCHANT_patch_private_product_option_unit_precision_level ( - pis->unit_precision_level)); - } - else - { + GNUNET_assert ( + GNUNET_OK == TALER_MERCHANT_patch_private_product_set_options ( pis->iph, TALER_MERCHANT_patch_private_product_option_total_stock_frac ( @@ -339,8 +330,7 @@ patch_product_run (void *cls, TALER_MERCHANT_patch_private_product_option_unit_allow_fraction ( pis->unit_allow_fraction), TALER_MERCHANT_patch_private_product_option_unit_precision_level ( - pis->unit_precision_level)); - } + pis->unit_precision_level))); } { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_patch_webhook.c b/src/testing/testing_api_cmd_patch_webhook.c @@ -156,10 +156,18 @@ patch_webhook_run (void *cls, pis->webhook_id, pis->event_type, pis->url, - pis->http_method, - pis->header_template, - pis->body_template); + pis->http_method); GNUNET_assert (NULL != pis->iph); + if (NULL != pis->header_template) + TALER_MERCHANT_patch_private_webhook_set_options ( + pis->iph, + TALER_MERCHANT_patch_private_webhook_option_header_template ( + pis->header_template)); + if (NULL != pis->body_template) + TALER_MERCHANT_patch_private_webhook_set_options ( + pis->iph, + TALER_MERCHANT_patch_private_webhook_option_body_template ( + pis->body_template)); { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_post_instances.c b/src/testing/testing_api_cmd_post_instances.c @@ -170,12 +170,18 @@ post_instances_run ( pis->name, pis->address, pis->jurisdiction, - pis->use_stefan, - pis->default_wire_transfer_delay, - pis->default_pay_delay, - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, - 15), - pis->auth_token); + pis->use_stefan); + TALER_MERCHANT_post_management_instances_set_options ( + pis->iph, + TALER_MERCHANT_post_management_instances_option_default_wire_transfer_delay ( + pis->default_wire_transfer_delay), + TALER_MERCHANT_post_management_instances_option_default_pay_delay ( + pis->default_pay_delay), + TALER_MERCHANT_post_management_instances_option_default_refund_delay ( + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, + 15)), + TALER_MERCHANT_post_management_instances_option_auth_password ( + pis->auth_token)); { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_post_otp_devices.c b/src/testing/testing_api_cmd_post_otp_devices.c @@ -151,8 +151,12 @@ post_otp_devices_run (void *cls, tis->otp_device_id, tis->otp_device_description, tis->otp_key, - tis->otp_alg, - tis->otp_ctr); + tis->otp_alg); + GNUNET_assert (GNUNET_OK == + TALER_MERCHANT_post_private_otp_devices_set_options ( + tis->iph, + TALER_MERCHANT_post_private_otp_devices_option_otp_ctr ( + tis->otp_ctr))); { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_post_products.c b/src/testing/testing_api_cmd_post_products.c @@ -309,60 +309,40 @@ post_products_run (void *cls, pis->product_id, pis->description, pis->unit, - &pis->price, - pis->image, - pis->total_stock); - if (NULL != pis->description_i18n) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_description_i18n ( - pis->description_i18n)); - if (NULL != pis->taxes) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_taxes ( - pis->taxes)); - if (NULL != pis->address) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_address ( - pis->address)); - if (GNUNET_TIME_absolute_is_zero (pis->next_restock.abs_time) == 0) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_next_restock ( - pis->next_restock)); - if (0 < pis->minimum_age) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_minimum_age ( - pis->minimum_age)); - if (0 < pis->num_cats) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_categories ( - pis->num_cats, - pis->cats)); - if (pis->use_unit_price_array) - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_unit_prices ( - pis->unit_prices, - pis->unit_prices_len)); + pis->unit_prices_len, + pis->unit_prices); + GNUNET_assert (GNUNET_OK == + TALER_MERCHANT_post_private_products_set_options ( + pis->iph, + TALER_MERCHANT_post_private_products_option_description_i18n ( + pis->description_i18n), + TALER_MERCHANT_post_private_products_option_total_stock_val ( + pis->total_stock), + TALER_MERCHANT_post_private_products_option_taxes ( + pis->taxes), + TALER_MERCHANT_post_private_products_option_image ( + pis->image), + TALER_MERCHANT_post_private_products_option_address ( + pis->address), + TALER_MERCHANT_post_private_products_option_next_restock ( + pis->next_restock), + TALER_MERCHANT_post_private_products_option_minimum_age ( + pis->minimum_age), + TALER_MERCHANT_post_private_products_option_categories ( + pis->num_cats, + pis->cats))); if (pis->use_fractional) { - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_total_stock_frac ( - pis->total_stock_frac)); - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_unit_allow_fraction ( - pis->unit_allow_fraction)); - TALER_MERCHANT_post_private_products_set_options ( - pis->iph, - TALER_MERCHANT_post_private_products_option_unit_precision_level ( - pis->unit_precision_level)); + GNUNET_assert ( + GNUNET_OK == + TALER_MERCHANT_post_private_products_set_options ( + pis->iph, + TALER_MERCHANT_post_private_products_option_total_stock_frac ( + pis->total_stock_frac), + TALER_MERCHANT_post_private_products_option_unit_allow_fraction ( + pis->unit_allow_fraction), + TALER_MERCHANT_post_private_products_option_unit_precision_level ( + pis->unit_precision_level))); } { enum TALER_ErrorCode ec; diff --git a/src/testing/testing_api_cmd_post_units.c b/src/testing/testing_api_cmd_post_units.c @@ -133,10 +133,15 @@ post_unit_run (void *cls, pus->merchant_url, pus->unit_id, pus->unit_name_long, - pus->unit_name_short, - pus->unit_allow_fraction, - pus->unit_precision_level, - pus->unit_active); + pus->unit_name_short); + TALER_MERCHANT_post_private_units_set_options ( + pus->uph, + TALER_MERCHANT_post_private_units_option_unit_allow_fraction ( + pus->unit_allow_fraction), + TALER_MERCHANT_post_private_units_option_unit_precision_level ( + pus->unit_precision_level), + TALER_MERCHANT_post_private_units_option_unit_active ( + pus->unit_active)); if (NULL != pus->unit_name_long_i18n) TALER_MERCHANT_post_private_units_set_options ( pus->uph, diff --git a/src/testing/testing_api_cmd_post_webhooks.c b/src/testing/testing_api_cmd_post_webhooks.c @@ -155,9 +155,17 @@ post_webhooks_run (void *cls, wis->webhook_id, wis->event_type, wis->url, - wis->http_method, - wis->header_template, - wis->body_template); + wis->http_method); + if (NULL != wis->header_template) + TALER_MERCHANT_post_private_webhooks_set_options ( + wis->iph, + TALER_MERCHANT_post_private_webhooks_option_header_template ( + wis->header_template)); + if (NULL != wis->body_template) + TALER_MERCHANT_post_private_webhooks_set_options ( + wis->iph, + TALER_MERCHANT_post_private_webhooks_option_body_template ( + wis->body_template)); { enum TALER_ErrorCode ec;