merchant

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

commit c11d977c59648b1596ff72cc478db71723775650
parent f9cdf071c0b945b2f8584b00232a05f059562226
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 22 Mar 2026 15:36:33 +0100

rename fest: drop -new

Diffstat:
Dsrc/include/taler/taler-merchant/delete-management-instances-INSTANCE-new.h | 181-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-management-instances-INSTANCE.h | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Dsrc/include/taler/taler-merchant/delete-private-accounts-H_WIRE-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-accounts-H_WIRE.h | 79++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Dsrc/include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL.h | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/delete-private-orders-ORDER_ID-new.h | 180-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-orders-ORDER_ID.h | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Dsrc/include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-products-PRODUCT_ID.h | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/delete-private-tokens-SERIAL-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-tokens-SERIAL.h | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/delete-private-transfers-TID-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-transfers-TID.h | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/delete-private-units-UNIT-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-units-UNIT.h | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h | 110-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-config-new.h | 234-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-config.h | 97++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Dsrc/include/taler/taler-merchant/get-management-instances-INSTANCE-new.h | 190-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-management-instances-INSTANCE.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/get-management-instances-new.h | 166-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-management-instances.h | 74+++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Dsrc/include/taler/taler-merchant/get-orders-ORDER_ID-new.h | 356-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-orders-ORDER_ID.h | 275+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Dsrc/include/taler/taler-merchant/get-private-accounts-H_WIRE-new.h | 171-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-accounts-H_WIRE.h | 78++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Dsrc/include/taler/taler-merchant/get-private-accounts-new.h | 156-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-accounts.h | 72++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/get-private-donau-new.h | 191-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-donau.h | 76+++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Dsrc/include/taler/taler-merchant/get-private-kyc-new.h | 443-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-kyc.h | 350+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Dsrc/include/taler/taler-merchant/get-private-orders-ORDER_ID-new.h | 449-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-orders-ORDER_ID.h | 221++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Dsrc/include/taler/taler-merchant/get-private-orders-new.h | 528-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-orders.h | 475++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Dsrc/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h | 160-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h | 70++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Dsrc/include/taler/taler-merchant/get-private-otp-devices-new.h | 157-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-otp-devices.h | 72+++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-private-products-PRODUCT_ID-new.h | 216-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-products-PRODUCT_ID.h | 70++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Dsrc/include/taler/taler-merchant/get-private-products-new.h | 156-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-products.h | 72+++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-private-statistics-amount-SLUG-new.h | 342-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-statistics-amount-SLUG.h | 234++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Dsrc/include/taler/taler-merchant/get-private-statistics-counter-SLUG-new.h | 333-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-statistics-counter-SLUG.h | 221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Dsrc/include/taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h | 145-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-templates-TEMPLATE_ID.h | 70++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Dsrc/include/taler/taler-merchant/get-private-templates-new.h | 156-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-templates.h | 71++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.h | 196-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG.h | 71++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-private-transfers-new.h | 423-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-transfers.h | 330+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Dsrc/include/taler/taler-merchant/get-private-units-UNIT-new.h | 135-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-units-UNIT.h | 70++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Dsrc/include/taler/taler-merchant/get-private-units-new.h | 137-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-units.h | 67++++++++++++++++++++++++++++++++++++++++++++++---------------------
Dsrc/include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h | 156-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID.h | 135++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Dsrc/include/taler/taler-merchant/get-private-webhooks-new.h | 156-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-private-webhooks.h | 71++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-products-IMAGE_HASH-image-new.h | 135-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-products-IMAGE_HASH-image.h | 71++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/get-templates-TEMPLATE_ID-new.h | 135-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/get-templates-TEMPLATE_ID.h | 71++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/patch-management-instances-INSTANCE-new.h | 123-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-management-instances-INSTANCE.h | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Dsrc/include/taler/taler-merchant/patch-private-accounts-H_WIRE-new.h | 254-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-accounts-H_WIRE.h | 233+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Dsrc/include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h | 113-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Dsrc/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h | 117-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Dsrc/include/taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h | 336-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-products-PRODUCT_ID.h | 332++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Dsrc/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h | 115-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Dsrc/include/taler/taler-merchant/patch-private-units-UNIT-new.h | 376-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-units-UNIT.h | 365++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Dsrc/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h | 119-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Dsrc/include/taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h | 115-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-management-instances-INSTANCE-auth.h | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/post-management-instances-new.h | 129-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-management-instances.h | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/post-orders-ORDER_ID-abort-new.h | 210-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-orders-ORDER_ID-abort.h | 139+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Dsrc/include/taler/taler-merchant/post-orders-ORDER_ID-claim-new.h | 252-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-orders-ORDER_ID-claim.h | 195+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Dsrc/include/taler/taler-merchant/post-orders-ORDER_ID-paid-new.h | 225-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-orders-ORDER_ID-paid.h | 193++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Dsrc/include/taler/taler-merchant/post-orders-ORDER_ID-pay-new.h | 714-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-orders-ORDER_ID-pay.h | 564+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Dsrc/include/taler/taler-merchant/post-orders-ORDER_ID-refund-new.h | 216-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-orders-ORDER_ID-refund.h | 183+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Dsrc/include/taler/taler-merchant/post-private-accounts-new.h | 271-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-accounts.h | 208++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Dsrc/include/taler/taler-merchant/post-private-categories-new.h | 240-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-categories.h | 200++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Dsrc/include/taler/taler-merchant/post-private-donau-new.h | 220-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-donau.h | 205++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Dsrc/include/taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h | 143-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-orders-ORDER_ID-refund.h | 80+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Dsrc/include/taler/taler-merchant/post-private-orders-new.h | 472-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-orders.h | 430+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Dsrc/include/taler/taler-merchant/post-private-otp-devices-new.h | 121-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-otp-devices.h | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h | 251-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h | 247++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Dsrc/include/taler/taler-merchant/post-private-products-new.h | 459-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-products.h | 535++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/post-private-templates-new.h | 223-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-templates.h | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Dsrc/include/taler/taler-merchant/post-private-token-new.h | 119-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-token.h | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Dsrc/include/taler/taler-merchant/post-private-tokenfamilies-new.h | 261-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-tokenfamilies.h | 226++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Dsrc/include/taler/taler-merchant/post-private-transfers-new.h | 145-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-transfers.h | 85++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Dsrc/include/taler/taler-merchant/post-private-units-new.h | 255-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-units.h | 226++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Dsrc/include/taler/taler-merchant/post-private-webhooks-new.h | 123-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-private-webhooks.h | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/include/taler/taler-merchant/post-templates-TEMPLATE_ID-new.h | 298-------------------------------------------------------------------------------
Msrc/include/taler/taler-merchant/post-templates-TEMPLATE_ID.h | 290+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/include/taler/taler_merchant_service.h | 128++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/lib/Makefile.am | 134++++++++++++++++++++++++++++++++++++++++----------------------------------------
Dsrc/lib/merchant_api_delete-management-instances-INSTANCE-new.c | 240-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-management-instances-INSTANCE.c | 246++++++++++++++++++++++++++++++++++++++++---------------------------------------
Dsrc/lib/merchant_api_delete-private-accounts-H_WIRE-new.c | 204-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-accounts-H_WIRE.c | 165++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_delete-private-donau-DONAU_SERIAL-new.c | 194-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-donau-DONAU_SERIAL.c | 195+++++++++++++++++++++++++++++++++++++++-----------------------------------------
Dsrc/lib/merchant_api_delete-private-orders-ORDER_ID-new.c | 230-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-orders-ORDER_ID.c | 203++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Dsrc/lib/merchant_api_delete-private-otp-devices-DEVICE_ID-new.c | 202-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-otp-devices-DEVICE_ID.c | 170++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_delete-private-products-PRODUCT_ID-new.c | 202-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-products-PRODUCT_ID.c | 170++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_delete-private-templates-TEMPLATE_ID-new.c | 202-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-templates-TEMPLATE_ID.c | 172++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_delete-private-tokens-SERIAL-new.c | 198-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-tokens-SERIAL.c | 166++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_delete-private-transfers-TID-new.c | 201-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-transfers-TID.c | 169+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_delete-private-units-UNIT-new.c | 202-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-units-UNIT.c | 191+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c | 203-------------------------------------------------------------------------------
Msrc/lib/merchant_api_delete-private-webhooks-WEBHOOK_ID.c | 171++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_get-config-new.c | 335-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-config.c | 149+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-management-instances-INSTANCE-new.c | 256-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-management-instances-INSTANCE.c | 141+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_get-management-instances-new.c | 277-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-management-instances.c | 178+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-orders-ORDER_ID-new.c | 335-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-orders-ORDER_ID.c | 367+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-private-accounts-H_WIRE-new.c | 238-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-accounts-H_WIRE.c | 177+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_get-private-accounts-new.c | 264-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-accounts.c | 153++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_get-private-donau-new.c | 302------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-donau.c | 331++++++++++++++++++++++++++++++++++++++++---------------------------------------
Dsrc/lib/merchant_api_get-private-kyc-new.c | 541-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-kyc.c | 332+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-private-orders-ORDER_ID-new.c | 573-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-orders-ORDER_ID.c | 375+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-private-orders-new.c | 522-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-orders.c | 400+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Dsrc/lib/merchant_api_get-private-otp-devices-DEVICE_ID-new.c | 231-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-otp-devices-DEVICE_ID.c | 165++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_get-private-otp-devices-new.c | 264-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-otp-devices.c | 178+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-private-products-PRODUCT_ID-new.c | 270-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-products-PRODUCT_ID.c | 133++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dsrc/lib/merchant_api_get-private-products-new.c | 265-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-products.c | 201++++++++++++++++++++++++++++++++++++++++---------------------------------------
Dsrc/lib/merchant_api_get-private-statistics-amount-SLUG-new.c | 455-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-statistics-amount-SLUG.c | 273++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dsrc/lib/merchant_api_get-private-statistics-counter-SLUG-new.c | 400-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-statistics-counter-SLUG.c | 281++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dsrc/lib/merchant_api_get-private-templates-TEMPLATE_ID-new.c | 222-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-templates-TEMPLATE_ID.c | 135++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dsrc/lib/merchant_api_get-private-templates-new.c | 265-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-templates.c | 156++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c | 242-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c | 188++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_get-private-transfers-new.c | 417-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-transfers.c | 409+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Dsrc/lib/merchant_api_get-private-units-UNIT-new.c | 274-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-units-UNIT.c | 171+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_get-private-units-new.c | 345-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-units.c | 166+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_get-private-webhooks-WEBHOOK_ID-new.c | 227-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-webhooks-WEBHOOK_ID.c | 194+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Dsrc/lib/merchant_api_get-private-webhooks-new.c | 265-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-private-webhooks.c | 155++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_get-products-IMAGE_HASH-image-new.c | 212-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-products-IMAGE_HASH-image.c | 167+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_get-templates-TEMPLATE_ID-new.c | 216-------------------------------------------------------------------------------
Msrc/lib/merchant_api_get-templates-TEMPLATE_ID.c | 157+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_patch-management-instances-INSTANCE-new.c | 313-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-management-instances-INSTANCE.c | 294+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_patch-private-accounts-H_WIRE-new.c | 295-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-accounts-H_WIRE.c | 265++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dsrc/lib/merchant_api_patch-private-orders-ORDER_ID-forget-new.c | 279-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-orders-ORDER_ID-forget.c | 229++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_patch-private-otp-devices-DEVICE_ID-new.c | 284-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-otp-devices-DEVICE_ID.c | 252++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_patch-private-products-PRODUCT_ID-new.c | 465-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-products-PRODUCT_ID.c | 471+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Dsrc/lib/merchant_api_patch-private-templates-TEMPLATE_ID-new.c | 282-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-templates-TEMPLATE_ID.c | 217+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_patch-private-units-UNIT-new.c | 378-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-units-UNIT.c | 397++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Dsrc/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c | 300-------------------------------------------------------------------------------
Msrc/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID.c | 236+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Dsrc/lib/merchant_api_post-management-instances-INSTANCE-auth-new.c | 254-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-management-instances-INSTANCE-auth.c | 215++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_post-management-instances-new.c | 333-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-management-instances.c | 281+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Dsrc/lib/merchant_api_post-orders-ORDER_ID-abort-new.c | 432-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-orders-ORDER_ID-abort.c | 272+++++++++++++++++++++++++++++++++++++++----------------------------------------
Dsrc/lib/merchant_api_post-orders-ORDER_ID-claim-new.c | 294-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-orders-ORDER_ID-claim.c | 246++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Dsrc/lib/merchant_api_post-orders-ORDER_ID-paid-new.c | 298-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-orders-ORDER_ID-paid.c | 259++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_post-orders-ORDER_ID-pay-new.c | 1123-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-orders-ORDER_ID-pay.c | 1117+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Dsrc/lib/merchant_api_post-orders-ORDER_ID-refund-new.c | 370-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-orders-ORDER_ID-refund.c | 299+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_post-private-accounts-new.c | 298-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-accounts.c | 200+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Dsrc/lib/merchant_api_post-private-categories-new.c | 286-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-categories.c | 261+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Dsrc/lib/merchant_api_post-private-donau-new.c | 256-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-donau.c | 251++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Dsrc/lib/merchant_api_post-private-orders-ORDER_ID-refund-new.c | 267-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-orders-ORDER_ID-refund.c | 211+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_post-private-orders-new.c | 510-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-orders.c | 529+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Dsrc/lib/merchant_api_post-private-otp-devices-new.c | 273-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-otp-devices.c | 234++++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Dsrc/lib/merchant_api_post-private-products-PRODUCT_ID-lock-new.c | 314-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-products-PRODUCT_ID-lock.c | 319++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_post-private-products-new.c | 498-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-products.c | 615++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_post-private-templates-new.c | 287-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-templates.c | 506+++++++++++++++++++++++--------------------------------------------------------
Dsrc/lib/merchant_api_post-private-token-new.c | 258-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-token.c | 269+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Dsrc/lib/merchant_api_post-private-tokenfamilies-new.c | 357-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-tokenfamilies.c | 326+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Dsrc/lib/merchant_api_post-private-transfers-new.c | 286-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-transfers.c | 240++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dsrc/lib/merchant_api_post-private-units-new.c | 312-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-units.c | 310+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Dsrc/lib/merchant_api_post-private-webhooks-new.c | 283-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-private-webhooks.c | 247++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Dsrc/lib/merchant_api_post-templates-TEMPLATE_ID-new.c | 330-------------------------------------------------------------------------------
Msrc/lib/merchant_api_post-templates-TEMPLATE_ID.c | 363++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/testing/testing_api_cmd_abort_order.c | 2+-
Msrc/testing/testing_api_cmd_claim_order.c | 2+-
Msrc/testing/testing_api_cmd_config.c | 2+-
Msrc/testing/testing_api_cmd_delete_account.c | 2+-
Msrc/testing/testing_api_cmd_delete_donau_instances.c | 2+-
Msrc/testing/testing_api_cmd_delete_instance.c | 2+-
Msrc/testing/testing_api_cmd_delete_order.c | 2+-
Msrc/testing/testing_api_cmd_delete_otp_device.c | 2+-
Msrc/testing/testing_api_cmd_delete_product.c | 2+-
Msrc/testing/testing_api_cmd_delete_template.c | 2+-
Msrc/testing/testing_api_cmd_delete_transfer.c | 2+-
Msrc/testing/testing_api_cmd_delete_unit.c | 2+-
Msrc/testing/testing_api_cmd_delete_webhook.c | 2+-
Msrc/testing/testing_api_cmd_forget_order.c | 2+-
Msrc/testing/testing_api_cmd_get_donau_instances.c | 2+-
Msrc/testing/testing_api_cmd_get_instance.c | 2+-
Msrc/testing/testing_api_cmd_get_instances.c | 2+-
Msrc/testing/testing_api_cmd_get_orders.c | 2+-
Msrc/testing/testing_api_cmd_get_otp_device.c | 2+-
Msrc/testing/testing_api_cmd_get_otp_devices.c | 2+-
Msrc/testing/testing_api_cmd_get_product.c | 2+-
Msrc/testing/testing_api_cmd_get_product_image.c | 2+-
Msrc/testing/testing_api_cmd_get_products.c | 2+-
Msrc/testing/testing_api_cmd_get_statisticsamount.c | 2+-
Msrc/testing/testing_api_cmd_get_statisticscounter.c | 2+-
Msrc/testing/testing_api_cmd_get_template.c | 2+-
Msrc/testing/testing_api_cmd_get_templates.c | 2+-
Msrc/testing/testing_api_cmd_get_transfers.c | 2+-
Msrc/testing/testing_api_cmd_get_unit.c | 2+-
Msrc/testing/testing_api_cmd_get_units.c | 2+-
Msrc/testing/testing_api_cmd_get_webhook.c | 2+-
Msrc/testing/testing_api_cmd_get_webhooks.c | 2+-
Msrc/testing/testing_api_cmd_instance_auth.c | 2+-
Msrc/testing/testing_api_cmd_instance_token.c | 4++--
Msrc/testing/testing_api_cmd_kyc_get.c | 2+-
Msrc/testing/testing_api_cmd_lock_product.c | 2+-
Msrc/testing/testing_api_cmd_merchant_get_order.c | 2+-
Msrc/testing/testing_api_cmd_patch_instance.c | 2+-
Msrc/testing/testing_api_cmd_patch_otp_device.c | 2+-
Msrc/testing/testing_api_cmd_patch_product.c | 2+-
Msrc/testing/testing_api_cmd_patch_template.c | 2+-
Msrc/testing/testing_api_cmd_patch_unit.c | 2+-
Msrc/testing/testing_api_cmd_patch_webhook.c | 2+-
Msrc/testing/testing_api_cmd_pay_order.c | 2+-
Msrc/testing/testing_api_cmd_post_account.c | 2+-
Msrc/testing/testing_api_cmd_post_categories.c | 2+-
Msrc/testing/testing_api_cmd_post_donau_instances.c | 2+-
Msrc/testing/testing_api_cmd_post_instances.c | 2+-
Msrc/testing/testing_api_cmd_post_orders.c | 4++--
Msrc/testing/testing_api_cmd_post_orders_paid.c | 2+-
Msrc/testing/testing_api_cmd_post_otp_devices.c | 2+-
Msrc/testing/testing_api_cmd_post_products.c | 2+-
Msrc/testing/testing_api_cmd_post_templates.c | 2+-
Msrc/testing/testing_api_cmd_post_tokenfamilies.c | 2+-
Msrc/testing/testing_api_cmd_post_transfers.c | 2+-
Msrc/testing/testing_api_cmd_post_units.c | 2+-
Msrc/testing/testing_api_cmd_post_using_templates.c | 4++--
Msrc/testing/testing_api_cmd_post_webhooks.c | 2+-
Msrc/testing/testing_api_cmd_refund_order.c | 2+-
Msrc/testing/testing_api_cmd_wallet_get_order.c | 2+-
Msrc/testing/testing_api_cmd_wallet_get_template.c | 2+-
Msrc/testing/testing_api_cmd_wallet_post_orders_refund.c | 2+-
332 files changed, 18581 insertions(+), 45636 deletions(-)

diff --git a/src/include/taler/taler-merchant/delete-management-instances-INSTANCE-new.h b/src/include/taler/taler-merchant/delete-management-instances-INSTANCE-new.h @@ -1,181 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-management-instances-INSTANCE-new.h - * @brief C interface for DELETE /management/instances/$INSTANCE - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_MANAGEMENT_INSTANCES_INSTANCE_NEW_H -#define _TALER_MERCHANT__DELETE_MANAGEMENT_INSTANCES_INSTANCE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /management/instances/$INSTANCE operation. - */ -struct TALER_MERCHANT_DeleteManagementInstanceHandle; - - -/** - * Set up DELETE /management/instances/$INSTANCE operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param instance_id identifier of the instance to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeleteManagementInstanceHandle * -TALER_MERCHANT_delete_management_instance_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id); - - -/** - * Options for DELETE /management/instances/$INSTANCE. - */ -enum TALER_MERCHANT_DeleteManagementInstanceOption -{ - /** - * Sentinel value, end of options. - */ - TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END = 0, - - /** - * If set, purge (hard delete) the instance, removing all data. - * Without this option, a soft delete is performed (preserves data). - * Value type: none (presence of option means purge=yes). - */ - TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_PURGE -}; - - -/** - * Value for a DELETE /management/instances/$INSTANCE option. - */ -struct TALER_MERCHANT_DeleteManagementInstanceOptionValue -{ - /** - * Which option is being set. - */ - enum TALER_MERCHANT_DeleteManagementInstanceOption option; -}; - - -/** - * Set options for DELETE /management/instances/$INSTANCE operation. - * - * @param[in,out] handle the handle to set options for - * @param num_options length of the @a options array - * @param options array of option values (terminated with _END) - */ -void -TALER_MERCHANT_delete_management_instance_set_options_ ( - struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle, - unsigned int num_options, - const struct TALER_MERCHANT_DeleteManagementInstanceOptionValue options[]); - - -/** - * Maximum number of options for set_options macro. - */ -#define TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTIONS_ARRAY_MAX_SIZE 4 - -/** - * Set options for DELETE /management/instances/$INSTANCE operation. - * Variadic macro wrapper around - * #TALER_MERCHANT_delete_management_instance_set_options_(). - * - * @param handle the handle to set options for - * @param ... option values (automatically terminated with _END) - */ -#define TALER_MERCHANT_delete_management_instance_set_options(handle, ...) \ - do { \ - struct TALER_MERCHANT_DeleteManagementInstanceOptionValue __opts[] = { \ - __VA_ARGS__, \ - { .option = TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END } \ - }; \ - TALER_MERCHANT_delete_management_instance_set_options_ ( \ - handle, \ - sizeof (__opts) / sizeof (__opts[0]) - 1, \ - __opts); \ - } while (0) - - -/** - * Response details for a DELETE /management/instances/$INSTANCE request. - */ -struct TALER_MERCHANT_DeleteManagementInstanceResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeleteManagementInstanceCallback. - */ -#define TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /management/instances/$INSTANCE request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeleteManagementInstanceCallback)( - TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeleteManagementInstanceResponse *result); - - -/** - * Start DELETE /management/instances/$INSTANCE operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_management_instance_start ( - struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle, - TALER_MERCHANT_DeleteManagementInstanceCallback cb, - TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /management/instances/$INSTANCE operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_management_instance_cancel ( - struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_MANAGEMENT_INSTANCES_INSTANCE_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-management-instances-INSTANCE.h b/src/include/taler/taler-merchant/delete-management-instances-INSTANCE.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-management-instances-INSTANCE.h - * @brief C interface for DELETE /management/instances/$INSTANCE of the merchant backend + * @brief C interface for DELETE /management/instances/$INSTANCE * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_MANAGEMENT_INSTANCES_INSTANCE_H @@ -26,69 +26,156 @@ /** - * Handle for a DELETE /management/instances/$INSTANCE request. + * Handle for a DELETE /management/instances/$INSTANCE operation. */ -struct TALER_MERCHANT_InstanceDeleteHandle; +struct TALER_MERCHANT_DeleteManagementInstanceHandle; /** - * Callback for a DELETE /management/instances/$INSTANCE request. + * Set up DELETE /management/instances/$INSTANCE operation. + * Note that you must explicitly start the operation after setup. * - * @param cls closure - * @param hr HTTP response details + * @param ctx curl context + * @param url merchant backend base URL + * @param instance_id identifier of the instance to delete + * @return handle to operation, NULL on error */ -typedef void -(*TALER_MERCHANT_InstanceDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +struct TALER_MERCHANT_DeleteManagementInstanceHandle * +TALER_MERCHANT_delete_management_instance_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id); + + +/** + * Options for DELETE /management/instances/$INSTANCE. + */ +enum TALER_MERCHANT_DeleteManagementInstanceOption +{ + /** + * Sentinel value, end of options. + */ + TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END = 0, + + /** + * If set, purge (hard delete) the instance, removing all data. + * Without this option, a soft delete is performed (preserves data). + * Value type: none (presence of option means purge=yes). + */ + TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_PURGE +}; + + +/** + * Value for a DELETE /management/instances/$INSTANCE option. + */ +struct TALER_MERCHANT_DeleteManagementInstanceOptionValue +{ + /** + * Which option is being set. + */ + enum TALER_MERCHANT_DeleteManagementInstanceOption option; +}; /** - * Issue a DELETE /management/instances/$INSTANCE request (soft delete, - * preserves data). + * Set options for DELETE /management/instances/$INSTANCE operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the instance to delete - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @param[in,out] handle the handle to set options for + * @param num_options length of the @a options array + * @param options array of option values (terminated with _END) + */ +void +TALER_MERCHANT_delete_management_instance_set_options_ ( + struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle, + unsigned int num_options, + const struct TALER_MERCHANT_DeleteManagementInstanceOptionValue options[]); + + +/** + * Maximum number of options for set_options macro. */ -struct TALER_MERCHANT_InstanceDeleteHandle * -TALER_MERCHANT_instance_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceDeleteCallback cb, - void *cb_cls); +#define TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTIONS_ARRAY_MAX_SIZE 4 + +/** + * Set options for DELETE /management/instances/$INSTANCE operation. + * Variadic macro wrapper around + * #TALER_MERCHANT_delete_management_instance_set_options_(). + * + * @param handle the handle to set options for + * @param ... option values (automatically terminated with _END) + */ +#define TALER_MERCHANT_delete_management_instance_set_options(handle, ...) \ + do { \ + struct TALER_MERCHANT_DeleteManagementInstanceOptionValue __opts[] = { \ + __VA_ARGS__, \ + { .option = TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END } \ + }; \ + TALER_MERCHANT_delete_management_instance_set_options_ ( \ + handle, \ + sizeof (__opts) / sizeof (__opts[0]) - 1, \ + __opts); \ + } while (0) + + +/** + * Response details for a DELETE /management/instances/$INSTANCE request. + */ +struct TALER_MERCHANT_DeleteManagementInstanceResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeleteManagementInstanceCallback. + */ +#define TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /management/instances/$INSTANCE request. + * + * @param cls closure + * @param result result returned by the HTTP server + */ +typedef void +(*TALER_MERCHANT_DeleteManagementInstanceCallback)( + TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeleteManagementInstanceResponse *result); /** - * Issue a DELETE /management/instances/$INSTANCE request with purge=yes - * (hard delete, removes all data). + * Start DELETE /management/instances/$INSTANCE operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the instance to purge - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_InstanceDeleteHandle * -TALER_MERCHANT_instance_purge (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_management_instance_start ( + struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle, + TALER_MERCHANT_DeleteManagementInstanceCallback cb, + TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /management/instances/$INSTANCE request. + * Cancel DELETE /management/instances/$INSTANCE operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] idh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_instance_delete_cancel ( - struct TALER_MERCHANT_InstanceDeleteHandle *idh); +TALER_MERCHANT_delete_management_instance_cancel ( + struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_MANAGEMENT_INSTANCES_INSTANCE_H */ diff --git a/src/include/taler/taler-merchant/delete-private-accounts-H_WIRE-new.h b/src/include/taler/taler-merchant/delete-private-accounts-H_WIRE-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-accounts-H_WIRE-new.h - * @brief C interface for DELETE /private/accounts/$H_WIRE - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_ACCOUNTS_H_WIRE_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_ACCOUNTS_H_WIRE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/accounts/$H_WIRE operation. - */ -struct TALER_MERCHANT_DeletePrivateAccountHandle; - - -/** - * Set up DELETE /private/accounts/$H_WIRE operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param h_wire hash of the wire details identifying the account to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateAccountHandle * -TALER_MERCHANT_delete_private_account_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_MerchantWireHashP *h_wire); - - -/** - * Response details for a DELETE /private/accounts/$H_WIRE request. - */ -struct TALER_MERCHANT_DeletePrivateAccountResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateAccountCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/accounts/$H_WIRE request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateAccountCallback)( - TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateAccountResponse *result); - - -/** - * Start DELETE /private/accounts/$H_WIRE operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_account_start ( - struct TALER_MERCHANT_DeletePrivateAccountHandle *handle, - TALER_MERCHANT_DeletePrivateAccountCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/accounts/$H_WIRE operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_account_cancel ( - struct TALER_MERCHANT_DeletePrivateAccountHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_ACCOUNTS_H_WIRE_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-accounts-H_WIRE.h b/src/include/taler/taler-merchant/delete-private-accounts-H_WIRE.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-accounts-H_WIRE.h - * @brief C interface for DELETE /private/accounts/$H_WIRE of the merchant backend + * @brief C interface for DELETE /private/accounts/$H_WIRE * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_ACCOUNTS_H_WIRE_H @@ -26,64 +26,85 @@ /** - * Handle for a DELETE /private/accounts/$H_WIRE request. + * Handle for a DELETE /private/accounts/$H_WIRE operation. */ -struct TALER_MERCHANT_AccountDeleteHandle; +struct TALER_MERCHANT_DeletePrivateAccountHandle; + + +/** + * Set up DELETE /private/accounts/$H_WIRE operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param h_wire hash of the wire details identifying the account to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateAccountHandle * +TALER_MERCHANT_delete_private_account_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_MerchantWireHashP *h_wire); /** * Response details for a DELETE /private/accounts/$H_WIRE request. */ -struct TALER_MERCHANT_AccountDeleteResponse +struct TALER_MERCHANT_DeletePrivateAccountResponse { - /** * HTTP response details. */ struct TALER_MERCHANT_HttpResponse hr; - }; +#ifndef TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE /** - * Callback for a DELETE /private/accounts/$H_WIRE request. + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateAccountCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/accounts/$H_WIRE request. * * @param cls closure - * @param adr response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_AccountDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_AccountDeleteResponse *adr); +(*TALER_MERCHANT_DeletePrivateAccountCallback)( + TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateAccountResponse *result); /** - * Issue a DELETE /private/accounts/$H_WIRE request to remove a wire account. + * Start DELETE /private/accounts/$H_WIRE operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param h_wire hash of the wire details identifying the account to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_AccountDeleteHandle * -TALER_MERCHANT_account_delete ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MerchantWireHashP *h_wire, - TALER_MERCHANT_AccountDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_account_start ( + struct TALER_MERCHANT_DeletePrivateAccountHandle *handle, + TALER_MERCHANT_DeletePrivateAccountCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/accounts/$H_WIRE request. + * Cancel DELETE /private/accounts/$H_WIRE operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] adh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_account_delete_cancel ( - struct TALER_MERCHANT_AccountDeleteHandle *adh); +TALER_MERCHANT_delete_private_account_cancel ( + struct TALER_MERCHANT_DeletePrivateAccountHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_ACCOUNTS_H_WIRE_H */ diff --git a/src/include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL-new.h b/src/include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL-new.h - * @brief C interface for DELETE /private/donau/$DONAU_SERIAL - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_DONAU_DONAU_SERIAL_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_DONAU_DONAU_SERIAL_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/donau/$DONAU_SERIAL operation. - */ -struct TALER_MERCHANT_DeletePrivateDonauHandle; - - -/** - * Set up DELETE /private/donau/$DONAU_SERIAL operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param charity_id charity identifier to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateDonauHandle * -TALER_MERCHANT_delete_private_donau_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - uint64_t charity_id); - - -/** - * Response details for a DELETE /private/donau/$DONAU_SERIAL request. - */ -struct TALER_MERCHANT_DeletePrivateDonauResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateDonauCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/donau/$DONAU_SERIAL request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateDonauCallback)( - TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateDonauResponse *result); - - -/** - * Start DELETE /private/donau/$DONAU_SERIAL operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_donau_start ( - struct TALER_MERCHANT_DeletePrivateDonauHandle *handle, - TALER_MERCHANT_DeletePrivateDonauCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/donau/$DONAU_SERIAL operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_donau_cancel ( - struct TALER_MERCHANT_DeletePrivateDonauHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_DONAU_DONAU_SERIAL_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL.h b/src/include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-donau-DONAU_SERIAL.h - * @brief C interface for DELETE /private/donau/$DONAU_SERIAL of the merchant backend + * @brief C interface for DELETE /private/donau/$DONAU_SERIAL * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_DONAU_DONAU_SERIAL_H @@ -26,50 +26,85 @@ /** - * Handle for a DELETE /private/donau/$DONAU_SERIAL request. + * Handle for a DELETE /private/donau/$DONAU_SERIAL operation. */ -struct TALER_MERCHANT_DonauInstanceDeleteHandle; +struct TALER_MERCHANT_DeletePrivateDonauHandle; /** - * Callback for a DELETE /private/donau/$DONAU_SERIAL request. + * Set up DELETE /private/donau/$DONAU_SERIAL operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param charity_id charity identifier to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateDonauHandle * +TALER_MERCHANT_delete_private_donau_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + uint64_t charity_id); + + +/** + * Response details for a DELETE /private/donau/$DONAU_SERIAL request. + */ +struct TALER_MERCHANT_DeletePrivateDonauResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateDonauCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/donau/$DONAU_SERIAL request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_DonauInstanceDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateDonauCallback)( + TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateDonauResponse *result); /** - * Issue a DELETE /private/donau/$DONAU_SERIAL request to unregister a charity. + * Start DELETE /private/donau/$DONAU_SERIAL operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param charity_id charity identifier to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_DonauInstanceDeleteHandle * -TALER_MERCHANT_donau_instance_delete ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - uint64_t charity_id, - TALER_MERCHANT_DonauInstanceDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_donau_start ( + struct TALER_MERCHANT_DeletePrivateDonauHandle *handle, + TALER_MERCHANT_DeletePrivateDonauCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/donau/$DONAU_SERIAL request. + * Cancel DELETE /private/donau/$DONAU_SERIAL operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] ddh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_donau_instance_delete_cancel ( - struct TALER_MERCHANT_DonauInstanceDeleteHandle *ddh); +TALER_MERCHANT_delete_private_donau_cancel ( + struct TALER_MERCHANT_DeletePrivateDonauHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_DONAU_DONAU_SERIAL_H */ diff --git a/src/include/taler/taler-merchant/delete-private-orders-ORDER_ID-new.h b/src/include/taler/taler-merchant/delete-private-orders-ORDER_ID-new.h @@ -1,180 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-orders-ORDER_ID-new.h - * @brief C interface for DELETE /private/orders/$ORDER_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_ORDERS_ORDER_ID_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_ORDERS_ORDER_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/orders/$ORDER_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateOrderHandle; - - -/** - * Set up DELETE /private/orders/$ORDER_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param order_id identifier of the order to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateOrderHandle * -TALER_MERCHANT_delete_private_order_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id); - - -/** - * Options for DELETE /private/orders/$ORDER_ID. - */ -enum TALER_MERCHANT_DeletePrivateOrderOption -{ - /** - * Sentinel value, end of options. - */ - TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_END = 0, - - /** - * If set, force deletion even if order has payments. - * Value type: none (presence of option means force=true). - */ - TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_FORCE -}; - - -/** - * Value for a DELETE /private/orders/$ORDER_ID option. - */ -struct TALER_MERCHANT_DeletePrivateOrderOptionValue -{ - /** - * Which option is being set. - */ - enum TALER_MERCHANT_DeletePrivateOrderOption option; -}; - - -/** - * Set options for DELETE /private/orders/$ORDER_ID operation. - * - * @param[in,out] handle the handle to set options for - * @param num_options length of the @a options array - * @param options array of option values (terminated with _END) - */ -void -TALER_MERCHANT_delete_private_order_set_options_ ( - struct TALER_MERCHANT_DeletePrivateOrderHandle *handle, - unsigned int num_options, - const struct TALER_MERCHANT_DeletePrivateOrderOptionValue options[]); - - -/** - * Maximum number of options for set_options macro. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTIONS_ARRAY_MAX_SIZE 4 - -/** - * Set options for DELETE /private/orders/$ORDER_ID operation. - * Variadic macro wrapper around - * #TALER_MERCHANT_delete_private_order_set_options_(). - * - * @param handle the handle to set options for - * @param ... option values (automatically terminated with _END) - */ -#define TALER_MERCHANT_delete_private_order_set_options(handle, ...) \ - do { \ - struct TALER_MERCHANT_DeletePrivateOrderOptionValue __opts[] = { \ - __VA_ARGS__, \ - { .option = TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_END } \ - }; \ - TALER_MERCHANT_delete_private_order_set_options_ ( \ - handle, \ - sizeof (__opts) / sizeof (__opts[0]) - 1, \ - __opts); \ - } while (0) - - -/** - * Response details for a DELETE /private/orders/$ORDER_ID request. - */ -struct TALER_MERCHANT_DeletePrivateOrderResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateOrderCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/orders/$ORDER_ID request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateOrderCallback)( - TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateOrderResponse *result); - - -/** - * Start DELETE /private/orders/$ORDER_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_order_start ( - struct TALER_MERCHANT_DeletePrivateOrderHandle *handle, - TALER_MERCHANT_DeletePrivateOrderCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/orders/$ORDER_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_order_cancel ( - struct TALER_MERCHANT_DeletePrivateOrderHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_ORDERS_ORDER_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-orders-ORDER_ID.h b/src/include/taler/taler-merchant/delete-private-orders-ORDER_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-orders-ORDER_ID.h - * @brief C interface for DELETE /private/orders/$ORDER_ID of the merchant backend + * @brief C interface for DELETE /private/orders/$ORDER_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_ORDERS_ORDER_ID_H @@ -26,51 +26,155 @@ /** - * Handle for a DELETE /private/orders/$ORDER_ID request. + * Handle for a DELETE /private/orders/$ORDER_ID operation. */ -struct TALER_MERCHANT_OrderDeleteHandle; +struct TALER_MERCHANT_DeletePrivateOrderHandle; /** - * Callback for a DELETE /private/orders/$ORDER_ID request. + * Set up DELETE /private/orders/$ORDER_ID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param order_id identifier of the order to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateOrderHandle * +TALER_MERCHANT_delete_private_order_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id); + + +/** + * Options for DELETE /private/orders/$ORDER_ID. + */ +enum TALER_MERCHANT_DeletePrivateOrderOption +{ + /** + * Sentinel value, end of options. + */ + TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_END = 0, + + /** + * If set, force deletion even if order has payments. + * Value type: none (presence of option means force=true). + */ + TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_FORCE +}; + + +/** + * Value for a DELETE /private/orders/$ORDER_ID option. + */ +struct TALER_MERCHANT_DeletePrivateOrderOptionValue +{ + /** + * Which option is being set. + */ + enum TALER_MERCHANT_DeletePrivateOrderOption option; +}; + + +/** + * Set options for DELETE /private/orders/$ORDER_ID operation. + * + * @param[in,out] handle the handle to set options for + * @param num_options length of the @a options array + * @param options array of option values (terminated with _END) + */ +void +TALER_MERCHANT_delete_private_order_set_options_ ( + struct TALER_MERCHANT_DeletePrivateOrderHandle *handle, + unsigned int num_options, + const struct TALER_MERCHANT_DeletePrivateOrderOptionValue options[]); + + +/** + * Maximum number of options for set_options macro. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTIONS_ARRAY_MAX_SIZE 4 + +/** + * Set options for DELETE /private/orders/$ORDER_ID operation. + * Variadic macro wrapper around + * #TALER_MERCHANT_delete_private_order_set_options_(). + * + * @param handle the handle to set options for + * @param ... option values (automatically terminated with _END) + */ +#define TALER_MERCHANT_delete_private_order_set_options(handle, ...) \ + do { \ + struct TALER_MERCHANT_DeletePrivateOrderOptionValue __opts[] = { \ + __VA_ARGS__, \ + { .option = TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_END } \ + }; \ + TALER_MERCHANT_delete_private_order_set_options_ ( \ + handle, \ + sizeof (__opts) / sizeof (__opts[0]) - 1, \ + __opts); \ + } while (0) + + +/** + * Response details for a DELETE /private/orders/$ORDER_ID request. + */ +struct TALER_MERCHANT_DeletePrivateOrderResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateOrderCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/orders/$ORDER_ID request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_OrderDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateOrderCallback)( + TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateOrderResponse *result); /** - * Issue a DELETE /private/orders/$ORDER_ID request. + * Start DELETE /private/orders/$ORDER_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order_id identifier of the order to delete - * @param force if true, force deletion even if order has payments - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderDeleteHandle * -TALER_MERCHANT_order_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - bool force, - TALER_MERCHANT_OrderDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_order_start ( + struct TALER_MERCHANT_DeletePrivateOrderHandle *handle, + TALER_MERCHANT_DeletePrivateOrderCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/orders/$ORDER_ID request. + * Cancel DELETE /private/orders/$ORDER_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] odh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_order_delete_cancel ( - struct TALER_MERCHANT_OrderDeleteHandle *odh); +TALER_MERCHANT_delete_private_order_cancel ( + struct TALER_MERCHANT_DeletePrivateOrderHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_ORDERS_ORDER_ID_H */ diff --git a/src/include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h b/src/include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h - * @brief C interface for DELETE /private/otp-devices/$DEVICE_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/otp-devices/$DEVICE_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle; - - -/** - * Set up DELETE /private/otp-devices/$DEVICE_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param otp_device_id identifier of the OTP device to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle * -TALER_MERCHANT_delete_private_otp_device_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id); - - -/** - * Response details for a DELETE /private/otp-devices/$DEVICE_ID request. - */ -struct TALER_MERCHANT_DeletePrivateOtpDeviceResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateOtpDeviceCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/otp-devices/$DEVICE_ID request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateOtpDeviceCallback)( - TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateOtpDeviceResponse *result); - - -/** - * Start DELETE /private/otp-devices/$DEVICE_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_otp_device_start ( - struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *handle, - TALER_MERCHANT_DeletePrivateOtpDeviceCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/otp-devices/$DEVICE_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_otp_device_cancel ( - struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h b/src/include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h - * @brief C interface for DELETE /private/otp-devices/$DEVICE_ID of the merchant backend + * @brief C interface for DELETE /private/otp-devices/$DEVICE_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_OTP_DEVICES_DEVICE_ID_H @@ -26,50 +26,85 @@ /** - * Handle for a DELETE /private/otp-devices/$DEVICE_ID request. + * Handle for a DELETE /private/otp-devices/$DEVICE_ID operation. */ -struct TALER_MERCHANT_OtpDeviceDeleteHandle; +struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle; /** - * Callback for a DELETE /private/otp-devices/$DEVICE_ID request. + * Set up DELETE /private/otp-devices/$DEVICE_ID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param otp_device_id identifier of the OTP device to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle * +TALER_MERCHANT_delete_private_otp_device_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *otp_device_id); + + +/** + * Response details for a DELETE /private/otp-devices/$DEVICE_ID request. + */ +struct TALER_MERCHANT_DeletePrivateOtpDeviceResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateOtpDeviceCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/otp-devices/$DEVICE_ID request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_OtpDeviceDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateOtpDeviceCallback)( + TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateOtpDeviceResponse *result); /** - * Issue a DELETE /private/otp-devices/$DEVICE_ID request. + * Start DELETE /private/otp-devices/$DEVICE_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param otp_device_id identifier of the OTP device to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OtpDeviceDeleteHandle * -TALER_MERCHANT_otp_device_delete ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *otp_device_id, - TALER_MERCHANT_OtpDeviceDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_otp_device_start ( + struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *handle, + TALER_MERCHANT_DeletePrivateOtpDeviceCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/otp-devices/$DEVICE_ID request. + * Cancel DELETE /private/otp-devices/$DEVICE_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tdh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_otp_device_delete_cancel ( - struct TALER_MERCHANT_OtpDeviceDeleteHandle *tdh); +TALER_MERCHANT_delete_private_otp_device_cancel ( + struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_OTP_DEVICES_DEVICE_ID_H */ diff --git a/src/include/taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h b/src/include/taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h - * @brief C interface for DELETE /private/products/$PRODUCT_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/products/$PRODUCT_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateProductHandle; - - -/** - * Set up DELETE /private/products/$PRODUCT_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param product_id identifier of the product to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateProductHandle * -TALER_MERCHANT_delete_private_product_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id); - - -/** - * Response details for a DELETE /private/products/$PRODUCT_ID request. - */ -struct TALER_MERCHANT_DeletePrivateProductResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateProductCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/products/$PRODUCT_ID request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateProductCallback)( - TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateProductResponse *result); - - -/** - * Start DELETE /private/products/$PRODUCT_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_product_start ( - struct TALER_MERCHANT_DeletePrivateProductHandle *handle, - TALER_MERCHANT_DeletePrivateProductCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/products/$PRODUCT_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_product_cancel ( - struct TALER_MERCHANT_DeletePrivateProductHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-products-PRODUCT_ID.h b/src/include/taler/taler-merchant/delete-private-products-PRODUCT_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-products-PRODUCT_ID.h - * @brief C interface for DELETE /private/products/$PRODUCT_ID of the merchant backend + * @brief C interface for DELETE /private/products/$PRODUCT_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_PRODUCTS_PRODUCT_ID_H @@ -26,49 +26,85 @@ /** - * Handle for a DELETE /private/products/$PRODUCT_ID request. + * Handle for a DELETE /private/products/$PRODUCT_ID operation. */ -struct TALER_MERCHANT_ProductDeleteHandle; +struct TALER_MERCHANT_DeletePrivateProductHandle; /** - * Callback for a DELETE /private/products/$PRODUCT_ID request. + * Set up DELETE /private/products/$PRODUCT_ID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param product_id identifier of the product to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateProductHandle * +TALER_MERCHANT_delete_private_product_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *product_id); + + +/** + * Response details for a DELETE /private/products/$PRODUCT_ID request. + */ +struct TALER_MERCHANT_DeletePrivateProductResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateProductCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/products/$PRODUCT_ID request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_ProductDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateProductCallback)( + TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateProductResponse *result); /** - * Issue a DELETE /private/products/$PRODUCT_ID request. + * Start DELETE /private/products/$PRODUCT_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param product_id identifier of the product to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductDeleteHandle * -TALER_MERCHANT_product_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - TALER_MERCHANT_ProductDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_product_start ( + struct TALER_MERCHANT_DeletePrivateProductHandle *handle, + TALER_MERCHANT_DeletePrivateProductCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/products/$PRODUCT_ID request. + * Cancel DELETE /private/products/$PRODUCT_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] pdh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_product_delete_cancel ( - struct TALER_MERCHANT_ProductDeleteHandle *pdh); +TALER_MERCHANT_delete_private_product_cancel ( + struct TALER_MERCHANT_DeletePrivateProductHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_PRODUCTS_PRODUCT_ID_H */ diff --git a/src/include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h b/src/include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h - * @brief C interface for DELETE /private/templates/$TEMPLATE_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/templates/$TEMPLATE_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateTemplateHandle; - - -/** - * Set up DELETE /private/templates/$TEMPLATE_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param template_id identifier of the template to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateTemplateHandle * -TALER_MERCHANT_delete_private_template_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id); - - -/** - * Response details for a DELETE /private/templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_DeletePrivateTemplateResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateTemplateCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/templates/$TEMPLATE_ID request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateTemplateCallback)( - TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateTemplateResponse *result); - - -/** - * Start DELETE /private/templates/$TEMPLATE_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_template_start ( - struct TALER_MERCHANT_DeletePrivateTemplateHandle *handle, - TALER_MERCHANT_DeletePrivateTemplateCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/templates/$TEMPLATE_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_template_cancel ( - struct TALER_MERCHANT_DeletePrivateTemplateHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h b/src/include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h - * @brief C interface for DELETE /private/templates/$TEMPLATE_ID of the merchant backend + * @brief C interface for DELETE /private/templates/$TEMPLATE_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_TEMPLATES_TEMPLATE_ID_H @@ -26,49 +26,85 @@ /** - * Handle for a DELETE /private/templates/$TEMPLATE_ID request. + * Handle for a DELETE /private/templates/$TEMPLATE_ID operation. */ -struct TALER_MERCHANT_TemplateDeleteHandle; +struct TALER_MERCHANT_DeletePrivateTemplateHandle; /** - * Callback for a DELETE /private/templates/$TEMPLATE_ID request. + * Set up DELETE /private/templates/$TEMPLATE_ID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param template_id identifier of the template to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateTemplateHandle * +TALER_MERCHANT_delete_private_template_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *template_id); + + +/** + * Response details for a DELETE /private/templates/$TEMPLATE_ID request. + */ +struct TALER_MERCHANT_DeletePrivateTemplateResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateTemplateCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/templates/$TEMPLATE_ID request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_TemplateDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateTemplateCallback)( + TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateTemplateResponse *result); /** - * Issue a DELETE /private/templates/$TEMPLATE_ID request. + * Start DELETE /private/templates/$TEMPLATE_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param template_id identifier of the template to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_TemplateDeleteHandle * -TALER_MERCHANT_template_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - TALER_MERCHANT_TemplateDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_template_start ( + struct TALER_MERCHANT_DeletePrivateTemplateHandle *handle, + TALER_MERCHANT_DeletePrivateTemplateCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/templates/$TEMPLATE_ID request. + * Cancel DELETE /private/templates/$TEMPLATE_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tdh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_template_delete_cancel ( - struct TALER_MERCHANT_TemplateDeleteHandle *tdh); +TALER_MERCHANT_delete_private_template_cancel ( + struct TALER_MERCHANT_DeletePrivateTemplateHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_TEMPLATES_TEMPLATE_ID_H */ diff --git a/src/include/taler/taler-merchant/delete-private-tokens-SERIAL-new.h b/src/include/taler/taler-merchant/delete-private-tokens-SERIAL-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-tokens-SERIAL-new.h - * @brief C interface for DELETE /private/tokens/$SERIAL - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_TOKENS_SERIAL_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_TOKENS_SERIAL_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/tokens/$SERIAL operation. - */ -struct TALER_MERCHANT_DeletePrivateTokenHandle; - - -/** - * Set up DELETE /private/tokens/$SERIAL operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param instance_id identifier of the instance - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateTokenHandle * -TALER_MERCHANT_delete_private_token_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id); - - -/** - * Response details for a DELETE /private/tokens/$SERIAL request. - */ -struct TALER_MERCHANT_DeletePrivateTokenResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateTokenCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/tokens/$SERIAL request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateTokenCallback)( - TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateTokenResponse *result); - - -/** - * Start DELETE /private/tokens/$SERIAL operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_token_start ( - struct TALER_MERCHANT_DeletePrivateTokenHandle *handle, - TALER_MERCHANT_DeletePrivateTokenCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/tokens/$SERIAL operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_token_cancel ( - struct TALER_MERCHANT_DeletePrivateTokenHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_TOKENS_SERIAL_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-tokens-SERIAL.h b/src/include/taler/taler-merchant/delete-private-tokens-SERIAL.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-tokens-SERIAL.h - * @brief C interface for DELETE /private/tokens/$SERIAL of the merchant backend + * @brief C interface for DELETE /private/tokens/$SERIAL * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_TOKENS_SERIAL_H @@ -26,50 +26,85 @@ /** - * Handle for a DELETE /private/tokens/$SERIAL request. + * Handle for a DELETE /private/tokens/$SERIAL operation. */ -struct TALER_MERCHANT_InstanceTokenDeleteHandle; +struct TALER_MERCHANT_DeletePrivateTokenHandle; /** - * Callback for a DELETE /private/tokens/$SERIAL request. + * Set up DELETE /private/tokens/$SERIAL operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param instance_id identifier of the instance + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateTokenHandle * +TALER_MERCHANT_delete_private_token_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id); + + +/** + * Response details for a DELETE /private/tokens/$SERIAL request. + */ +struct TALER_MERCHANT_DeletePrivateTokenResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateTokenCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/tokens/$SERIAL request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_InstanceTokenDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateTokenCallback)( + TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateTokenResponse *result); /** - * Issue a DELETE /private/tokens/$SERIAL request to revoke an access token. + * Start DELETE /private/tokens/$SERIAL operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the instance - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_InstanceTokenDeleteHandle * -TALER_MERCHANT_instance_token_delete ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceTokenDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_token_start ( + struct TALER_MERCHANT_DeletePrivateTokenHandle *handle, + TALER_MERCHANT_DeletePrivateTokenCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/tokens/$SERIAL request. + * Cancel DELETE /private/tokens/$SERIAL operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tdh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_instance_token_delete_cancel ( - struct TALER_MERCHANT_InstanceTokenDeleteHandle *tdh); +TALER_MERCHANT_delete_private_token_cancel ( + struct TALER_MERCHANT_DeletePrivateTokenHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_TOKENS_SERIAL_H */ diff --git a/src/include/taler/taler-merchant/delete-private-transfers-TID-new.h b/src/include/taler/taler-merchant/delete-private-transfers-TID-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-transfers-TID-new.h - * @brief C interface for DELETE /private/transfers/$TID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_TRANSFERS_TID_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_TRANSFERS_TID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/transfers/$TID operation. - */ -struct TALER_MERCHANT_DeletePrivateTransferHandle; - - -/** - * Set up DELETE /private/transfers/$TID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param wire_transfer_serial serial number of the wire transfer to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateTransferHandle * -TALER_MERCHANT_delete_private_transfer_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - uint64_t wire_transfer_serial); - - -/** - * Response details for a DELETE /private/transfers/$TID request. - */ -struct TALER_MERCHANT_DeletePrivateTransferResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateTransferCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/transfers/$TID request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateTransferCallback)( - TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateTransferResponse *result); - - -/** - * Start DELETE /private/transfers/$TID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_transfer_start ( - struct TALER_MERCHANT_DeletePrivateTransferHandle *handle, - TALER_MERCHANT_DeletePrivateTransferCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/transfers/$TID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_transfer_cancel ( - struct TALER_MERCHANT_DeletePrivateTransferHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_TRANSFERS_TID_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-transfers-TID.h b/src/include/taler/taler-merchant/delete-private-transfers-TID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-transfers-TID.h - * @brief C interface for DELETE /private/transfers/$TID of the merchant backend + * @brief C interface for DELETE /private/transfers/$TID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_TRANSFERS_TID_H @@ -26,50 +26,85 @@ /** - * Handle for a DELETE /private/transfers/$TID request. + * Handle for a DELETE /private/transfers/$TID operation. */ -struct TALER_MERCHANT_TransferDeleteHandle; +struct TALER_MERCHANT_DeletePrivateTransferHandle; /** - * Callback for a DELETE /private/transfers/$TID request. + * Set up DELETE /private/transfers/$TID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param wire_transfer_serial serial number of the wire transfer to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateTransferHandle * +TALER_MERCHANT_delete_private_transfer_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + uint64_t wire_transfer_serial); + + +/** + * Response details for a DELETE /private/transfers/$TID request. + */ +struct TALER_MERCHANT_DeletePrivateTransferResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateTransferCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/transfers/$TID request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_TransferDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateTransferCallback)( + TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateTransferResponse *result); /** - * Issue a DELETE /private/transfers/$TID request. + * Start DELETE /private/transfers/$TID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param wire_transfer_serial serial number of the wire transfer to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_TransferDeleteHandle * -TALER_MERCHANT_transfer_delete ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - uint64_t wire_transfer_serial, - TALER_MERCHANT_TransferDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_transfer_start ( + struct TALER_MERCHANT_DeletePrivateTransferHandle *handle, + TALER_MERCHANT_DeletePrivateTransferCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/transfers/$TID request. + * Cancel DELETE /private/transfers/$TID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tdh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_transfer_delete_cancel ( - struct TALER_MERCHANT_TransferDeleteHandle *tdh); +TALER_MERCHANT_delete_private_transfer_cancel ( + struct TALER_MERCHANT_DeletePrivateTransferHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_TRANSFERS_TID_H */ diff --git a/src/include/taler/taler-merchant/delete-private-units-UNIT-new.h b/src/include/taler/taler-merchant/delete-private-units-UNIT-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-units-UNIT-new.h - * @brief C interface for DELETE /private/units/$UNIT - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_UNITS_UNIT_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_UNITS_UNIT_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/units/$UNIT operation. - */ -struct TALER_MERCHANT_DeletePrivateUnitHandle; - - -/** - * Set up DELETE /private/units/$UNIT operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param unit_id identifier of the unit to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateUnitHandle * -TALER_MERCHANT_delete_private_unit_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *unit_id); - - -/** - * Response details for a DELETE /private/units/$UNIT request. - */ -struct TALER_MERCHANT_DeletePrivateUnitResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateUnitCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/units/$UNIT request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateUnitCallback)( - TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateUnitResponse *result); - - -/** - * Start DELETE /private/units/$UNIT operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_unit_start ( - struct TALER_MERCHANT_DeletePrivateUnitHandle *handle, - TALER_MERCHANT_DeletePrivateUnitCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/units/$UNIT operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_unit_cancel ( - struct TALER_MERCHANT_DeletePrivateUnitHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_UNITS_UNIT_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-units-UNIT.h b/src/include/taler/taler-merchant/delete-private-units-UNIT.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-units-UNIT.h - * @brief C interface for DELETE /private/units/$UNIT of the merchant backend + * @brief C interface for DELETE /private/units/$UNIT * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_UNITS_UNIT_H @@ -26,49 +26,85 @@ /** - * Handle for a DELETE /private/units/$UNIT request. + * Handle for a DELETE /private/units/$UNIT operation. */ -struct TALER_MERCHANT_UnitDeleteHandle; +struct TALER_MERCHANT_DeletePrivateUnitHandle; /** - * Callback for a DELETE /private/units/$UNIT request. + * Set up DELETE /private/units/$UNIT operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param unit_id identifier of the unit to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateUnitHandle * +TALER_MERCHANT_delete_private_unit_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *unit_id); + + +/** + * Response details for a DELETE /private/units/$UNIT request. + */ +struct TALER_MERCHANT_DeletePrivateUnitResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateUnitCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/units/$UNIT request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_UnitDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateUnitCallback)( + TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateUnitResponse *result); /** - * Issue a DELETE /private/units/$UNIT request. + * Start DELETE /private/units/$UNIT operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param unit_id identifier of the unit to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_UnitDeleteHandle * -TALER_MERCHANT_unit_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *unit_id, - TALER_MERCHANT_UnitDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_unit_start ( + struct TALER_MERCHANT_DeletePrivateUnitHandle *handle, + TALER_MERCHANT_DeletePrivateUnitCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/units/$UNIT request. + * Cancel DELETE /private/units/$UNIT operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] udh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_unit_delete_cancel ( - struct TALER_MERCHANT_UnitDeleteHandle *udh); +TALER_MERCHANT_delete_private_unit_cancel ( + struct TALER_MERCHANT_DeletePrivateUnitHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_UNITS_UNIT_H */ diff --git a/src/include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h b/src/include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h @@ -1,110 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h - * @brief C interface for DELETE /private/webhooks/$WEBHOOK_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__DELETE_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H -#define _TALER_MERCHANT__DELETE_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a DELETE /private/webhooks/$WEBHOOK_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateWebhookHandle; - - -/** - * Set up DELETE /private/webhooks/$WEBHOOK_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx curl context - * @param url merchant backend base URL - * @param webhook_id identifier of the webhook to delete - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_DeletePrivateWebhookHandle * -TALER_MERCHANT_delete_private_webhook_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id); - - -/** - * Response details for a DELETE /private/webhooks/$WEBHOOK_ID request. - */ -struct TALER_MERCHANT_DeletePrivateWebhookResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_DeletePrivateWebhookCallback. - */ -#define TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE */ - -/** - * Type of the function that receives the result of a - * DELETE /private/webhooks/$WEBHOOK_ID request. - * - * @param cls closure - * @param result result returned by the HTTP server - */ -typedef void -(*TALER_MERCHANT_DeletePrivateWebhookCallback)( - TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_DeletePrivateWebhookResponse *result); - - -/** - * Start DELETE /private/webhooks/$WEBHOOK_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_webhook_start ( - struct TALER_MERCHANT_DeletePrivateWebhookHandle *handle, - TALER_MERCHANT_DeletePrivateWebhookCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel DELETE /private/webhooks/$WEBHOOK_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_delete_private_webhook_cancel ( - struct TALER_MERCHANT_DeletePrivateWebhookHandle *handle); - - -#endif /* _TALER_MERCHANT__DELETE_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h b/src/include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h - * @brief C interface for DELETE /private/webhooks/$WEBHOOK_ID of the merchant backend + * @brief C interface for DELETE /private/webhooks/$WEBHOOK_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__DELETE_PRIVATE_WEBHOOKS_WEBHOOK_ID_H @@ -26,49 +26,85 @@ /** - * Handle for a DELETE /private/webhooks/$WEBHOOK_ID request. + * Handle for a DELETE /private/webhooks/$WEBHOOK_ID operation. */ -struct TALER_MERCHANT_WebhookDeleteHandle; +struct TALER_MERCHANT_DeletePrivateWebhookHandle; /** - * Callback for a DELETE /private/webhooks/$WEBHOOK_ID request. + * Set up DELETE /private/webhooks/$WEBHOOK_ID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx curl context + * @param url merchant backend base URL + * @param webhook_id identifier of the webhook to delete + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_DeletePrivateWebhookHandle * +TALER_MERCHANT_delete_private_webhook_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *webhook_id); + + +/** + * Response details for a DELETE /private/webhooks/$WEBHOOK_ID request. + */ +struct TALER_MERCHANT_DeletePrivateWebhookResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_DeletePrivateWebhookCallback. + */ +#define TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE */ + +/** + * Type of the function that receives the result of a + * DELETE /private/webhooks/$WEBHOOK_ID request. * * @param cls closure - * @param hr HTTP response details + * @param result result returned by the HTTP server */ typedef void -(*TALER_MERCHANT_WebhookDeleteCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_DeletePrivateWebhookCallback)( + TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_DeletePrivateWebhookResponse *result); /** - * Issue a DELETE /private/webhooks/$WEBHOOK_ID request. + * Start DELETE /private/webhooks/$WEBHOOK_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param webhook_id identifier of the webhook to delete - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_WebhookDeleteHandle * -TALER_MERCHANT_webhook_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *webhook_id, - TALER_MERCHANT_WebhookDeleteCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_webhook_start ( + struct TALER_MERCHANT_DeletePrivateWebhookHandle *handle, + TALER_MERCHANT_DeletePrivateWebhookCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls); /** - * Cancel a DELETE /private/webhooks/$WEBHOOK_ID request. + * Cancel DELETE /private/webhooks/$WEBHOOK_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] wdh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_webhook_delete_cancel ( - struct TALER_MERCHANT_WebhookDeleteHandle *wdh); +TALER_MERCHANT_delete_private_webhook_cancel ( + struct TALER_MERCHANT_DeletePrivateWebhookHandle *handle); -#endif +#endif /* _TALER_MERCHANT__DELETE_PRIVATE_WEBHOOKS_WEBHOOK_ID_H */ diff --git a/src/include/taler/taler-merchant/get-config-new.h b/src/include/taler/taler-merchant/get-config-new.h @@ -1,234 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-config-new.h - * @brief C interface for the GET /config endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_CONFIG_NEW_H -#define _TALER_MERCHANT__GET_CONFIG_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Version compatibility status for the merchant backend. - */ -enum TALER_MERCHANT_GetConfigVersionCompatibility -{ - /** - * The client and server are at the same version. - */ - TALER_MERCHANT_GET_CONFIG_VC_MATCH = 0, - - /** - * The server is running a newer API version. - */ - TALER_MERCHANT_GET_CONFIG_VC_NEWER = 1, - - /** - * The server is running an older API version. - */ - TALER_MERCHANT_GET_CONFIG_VC_OLDER = 2, - - /** - * The versions are incompatible. - */ - TALER_MERCHANT_GET_CONFIG_VC_INCOMPATIBLE = 4, - - /** - * A protocol error occurred. - */ - TALER_MERCHANT_GET_CONFIG_VC_PROTOCOL_ERROR = 8 -}; - - -/** - * Information about an exchange as returned in the config response. - */ -struct TALER_MERCHANT_GetConfigExchangeInfo -{ - - /** - * Base URL of the exchange. - */ - const char *base_url; - - /** - * Currency served by this exchange. - */ - const char *currency; - - /** - * Master public key of the exchange. - */ - struct TALER_MasterPublicKeyP master_pub; - -}; - - -/** - * Handle for a GET /config request. - */ -struct TALER_MERCHANT_GetConfigHandle; - - -/** - * Response details for a GET /config request. - */ -struct TALER_MERCHANT_GetConfigResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * API version string. - */ - const char *version; - - /** - * Currency used by this merchant backend. - */ - const char *currency; - - /** - * Compatibility status with the client library. - */ - enum TALER_MERCHANT_GetConfigVersionCompatibility compat; - - /** - * Number of exchanges in @a exchanges. - */ - unsigned int num_exchanges; - - /** - * Array of exchange configurations. - */ - const struct TALER_MERCHANT_GetConfigExchangeInfo *exchanges; - - /** - * Number of currency specifications in @a cspecs. - */ - unsigned int num_cspecs; - - /** - * Array of currency specifications. - */ - const struct TALER_CurrencySpecification *cspecs; - - /** - * Currency information returned by the backend. - */ - struct - { - /** - * Currency string. - */ - const char *currency; - - /** - * Version string. - */ - const char *version; - } ci; - - } ok; - - } details; - -}; - - -/** - * Set up GET /config operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetConfigHandle * -TALER_MERCHANT_get_config_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetConfigCallback. - */ -#define TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE */ - -/** - * Callback for a GET /config request. - * - * @param cls closure - * @param cr response details - */ -typedef void -(*TALER_MERCHANT_GetConfigCallback)( - TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetConfigResponse *cr); - - -/** - * Start GET /config operation. - * - * @param[in,out] gch operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_config_start ( - struct TALER_MERCHANT_GetConfigHandle *gch, - TALER_MERCHANT_GetConfigCallback cb, - TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /config operation. This function must not be called - * by clients after the TALER_MERCHANT_GetConfigCallback has been - * invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gch operation to cancel - */ -void -TALER_MERCHANT_get_config_cancel ( - struct TALER_MERCHANT_GetConfigHandle *gch); - - -#endif /* _TALER_MERCHANT__GET_CONFIG_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-config.h b/src/include/taler/taler-merchant/get-config.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-config.h - * @brief C interface for GET /config of the merchant backend + * @brief C interface for the GET /config endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_CONFIG_H @@ -26,47 +26,41 @@ /** - * Handle for a GET /config request. - */ -struct TALER_MERCHANT_ConfigGetHandle; - - -/** * Version compatibility status for the merchant backend. */ -enum TALER_MERCHANT_VersionCompatibility +enum TALER_MERCHANT_GetConfigVersionCompatibility { /** * The client and server are at the same version. */ - TALER_MERCHANT_VC_MATCH = 0, + TALER_MERCHANT_GET_CONFIG_VC_MATCH = 0, /** * The server is running a newer API version. */ - TALER_MERCHANT_VC_NEWER = 1, + TALER_MERCHANT_GET_CONFIG_VC_NEWER = 1, /** * The server is running an older API version. */ - TALER_MERCHANT_VC_OLDER = 2, + TALER_MERCHANT_GET_CONFIG_VC_OLDER = 2, /** * The versions are incompatible. */ - TALER_MERCHANT_VC_INCOMPATIBLE = 4, + TALER_MERCHANT_GET_CONFIG_VC_INCOMPATIBLE = 4, /** * A protocol error occurred. */ - TALER_MERCHANT_VC_PROTOCOL_ERROR = 8 + TALER_MERCHANT_GET_CONFIG_VC_PROTOCOL_ERROR = 8 }; /** * Information about an exchange as returned in the config response. */ -struct TALER_MERCHANT_ExchangeConfigInfo +struct TALER_MERCHANT_GetConfigExchangeInfo { /** @@ -88,9 +82,15 @@ struct TALER_MERCHANT_ExchangeConfigInfo /** + * Handle for a GET /config request. + */ +struct TALER_MERCHANT_GetConfigHandle; + + +/** * Response details for a GET /config request. */ -struct TALER_MERCHANT_ConfigResponse +struct TALER_MERCHANT_GetConfigResponse { /** @@ -123,7 +123,7 @@ struct TALER_MERCHANT_ConfigResponse /** * Compatibility status with the client library. */ - enum TALER_MERCHANT_VersionCompatibility compat; + enum TALER_MERCHANT_GetConfigVersionCompatibility compat; /** * Number of exchanges in @a exchanges. @@ -133,7 +133,7 @@ struct TALER_MERCHANT_ConfigResponse /** * Array of exchange configurations. */ - const struct TALER_MERCHANT_ExchangeConfigInfo *exchanges; + const struct TALER_MERCHANT_GetConfigExchangeInfo *exchanges; /** * Number of currency specifications in @a cspecs. @@ -169,41 +169,66 @@ struct TALER_MERCHANT_ConfigResponse /** + * Set up GET /config operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetConfigHandle * +TALER_MERCHANT_get_config_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetConfigCallback. + */ +#define TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE */ + +/** * Callback for a GET /config request. * * @param cls closure * @param cr response details */ typedef void -(*TALER_MERCHANT_ConfigCallback)( - void *cls, - const struct TALER_MERCHANT_ConfigResponse *cr); +(*TALER_MERCHANT_GetConfigCallback)( + TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetConfigResponse *cr); /** - * Issue a GET /config request to the merchant backend. + * Start GET /config operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param config_cb callback to invoke with the result - * @param config_cb_cls closure for @a config_cb - * @return handle for the request, NULL on hard error + * @param[in,out] gch operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ConfigGetHandle * -TALER_MERCHANT_config_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_ConfigCallback config_cb, - void *config_cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_config_start ( + struct TALER_MERCHANT_GetConfigHandle *gch, + TALER_MERCHANT_GetConfigCallback cb, + TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /config request. + * Cancel GET /config operation. This function must not be called + * by clients after the TALER_MERCHANT_GetConfigCallback has been + * invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] vgh handle to cancel + * @param[in] gch operation to cancel */ void -TALER_MERCHANT_config_get_cancel ( - struct TALER_MERCHANT_ConfigGetHandle *vgh); +TALER_MERCHANT_get_config_cancel ( + struct TALER_MERCHANT_GetConfigHandle *gch); -#endif +#endif /* _TALER_MERCHANT__GET_CONFIG_H */ diff --git a/src/include/taler/taler-merchant/get-management-instances-INSTANCE-new.h b/src/include/taler/taler-merchant/get-management-instances-INSTANCE-new.h @@ -1,190 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-management-instances-INSTANCE-new.h - * @brief C interface for GET /management/instances/$INSTANCE of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_NEW_H -#define _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /management/instances/$INSTANCE request. - */ -struct TALER_MERCHANT_GetManagementInstanceHandle; - - -/** - * Detailed information about a merchant instance. - */ -struct TALER_MERCHANT_GetManagementInstanceDetails -{ - - /** - * Human-readable name of the instance. - */ - const char *name; - - /** - * Public key of the merchant instance. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Whether to use the STEFAN curve for fee calculations. - */ - bool use_stefan; - - /** - * Default wire transfer delay. - */ - struct GNUNET_TIME_Relative default_wire_transfer_delay; - - /** - * Default payment deadline. - */ - struct GNUNET_TIME_Relative default_pay_delay; - - /** - * Default refund deadline. - */ - struct GNUNET_TIME_Relative default_refund_delay; - - /** - * Default wire transfer rounding interval. - */ - enum GNUNET_TIME_RounderInterval default_wire_transfer_rounding_interval; - - /** - * Merchant address (JSON). - */ - const json_t *address; - - /** - * Merchant jurisdiction (JSON). - */ - const json_t *jurisdiction; - -}; - - -/** - * Response details for a GET /management/instances/$INSTANCE request. - */ -struct TALER_MERCHANT_GetManagementInstanceResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Detailed information about the instance. - */ - struct TALER_MERCHANT_GetManagementInstanceDetails details; - - } ok; - - } details; - -}; - - -/** - * Set up GET /management/instances/$INSTANCE operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param instance_id identifier of the instance to retrieve, - * NULL for admin instance - * @return handle to operation - */ -struct TALER_MERCHANT_GetManagementInstanceHandle * -TALER_MERCHANT_get_management_instance_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id); - - -#ifndef TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetManagementInstanceCallback. - */ -#define TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE */ - -/** - * Callback for a GET /management/instances/$INSTANCE request. - * - * @param cls closure - * @param igr response details - */ -typedef void -(*TALER_MERCHANT_GetManagementInstanceCallback)( - TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetManagementInstanceResponse *igr); - - -/** - * Start GET /management/instances/$INSTANCE operation. - * - * @param[in,out] gmi operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_management_instance_start ( - struct TALER_MERCHANT_GetManagementInstanceHandle *gmi, - TALER_MERCHANT_GetManagementInstanceCallback cb, - TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /management/instances/$INSTANCE operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetManagementInstanceCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gmi operation to cancel - */ -void -TALER_MERCHANT_get_management_instance_cancel ( - struct TALER_MERCHANT_GetManagementInstanceHandle *gmi); - - -#endif /* _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-management-instances-INSTANCE.h b/src/include/taler/taler-merchant/get-management-instances-INSTANCE.h @@ -28,12 +28,13 @@ /** * Handle for a GET /management/instances/$INSTANCE request. */ -struct TALER_MERCHANT_InstanceGetHandle; +struct TALER_MERCHANT_GetManagementInstanceHandle; + /** * Detailed information about a merchant instance. */ -struct TALER_MERCHANT_InstanceDetails +struct TALER_MERCHANT_GetManagementInstanceDetails { /** @@ -87,7 +88,7 @@ struct TALER_MERCHANT_InstanceDetails /** * Response details for a GET /management/instances/$INSTANCE request. */ -struct TALER_MERCHANT_InstanceGetResponse +struct TALER_MERCHANT_GetManagementInstanceResponse { /** @@ -110,7 +111,7 @@ struct TALER_MERCHANT_InstanceGetResponse /** * Detailed information about the instance. */ - struct TALER_MERCHANT_InstanceDetails details; + struct TALER_MERCHANT_GetManagementInstanceDetails details; } ok; @@ -120,43 +121,70 @@ struct TALER_MERCHANT_InstanceGetResponse /** + * Set up GET /management/instances/$INSTANCE operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param instance_id identifier of the instance to retrieve, + * NULL for admin instance + * @return handle to operation + */ +struct TALER_MERCHANT_GetManagementInstanceHandle * +TALER_MERCHANT_get_management_instance_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id); + + +#ifndef TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetManagementInstanceCallback. + */ +#define TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE */ + +/** * Callback for a GET /management/instances/$INSTANCE request. * * @param cls closure * @param igr response details */ typedef void -(*TALER_MERCHANT_InstanceGetCallback)( - void *cls, - const struct TALER_MERCHANT_InstanceGetResponse *igr); +(*TALER_MERCHANT_GetManagementInstanceCallback)( + TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetManagementInstanceResponse *igr); /** - * Issue a GET /management/instances/$INSTANCE request. + * Start GET /management/instances/$INSTANCE operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the instance to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gmi operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_InstanceGetHandle * -TALER_MERCHANT_instance_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_management_instance_start ( + struct TALER_MERCHANT_GetManagementInstanceHandle *gmi, + TALER_MERCHANT_GetManagementInstanceCallback cb, + TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /management/instances/$INSTANCE request. + * Cancel GET /management/instances/$INSTANCE operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetManagementInstanceCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] igh handle to cancel + * @param[in] gmi operation to cancel */ void -TALER_MERCHANT_instance_get_cancel ( - struct TALER_MERCHANT_InstanceGetHandle *igh); +TALER_MERCHANT_get_management_instance_cancel ( + struct TALER_MERCHANT_GetManagementInstanceHandle *gmi); -#endif +#endif /* _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_H */ diff --git a/src/include/taler/taler-merchant/get-management-instances-new.h b/src/include/taler/taler-merchant/get-management-instances-new.h @@ -1,166 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-management-instances-new.h - * @brief C interface for the GET /management/instances endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_NEW_H -#define _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /management/instances request. - */ -struct TALER_MERCHANT_GetManagementInstancesHandle; - - -/** - * Information about one merchant instance. - */ -struct TALER_MERCHANT_GetManagementInstancesInstanceInfo -{ - - /** - * Instance identifier string. - */ - const char *id; - - /** - * Human-readable name of the instance. - */ - const char *name; - - /** - * Public key of the instance. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * JSON array of supported payment targets. - */ - const json_t *payment_targets; - -}; - - -/** - * Response details for a GET /management/instances request. - */ -struct TALER_MERCHANT_GetManagementInstancesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of instances in @a iis. - */ - unsigned int iis_length; - - /** - * Array of instance information. - */ - const struct TALER_MERCHANT_GetManagementInstancesInstanceInfo *iis; - - } ok; - - } details; - -}; - - -/** - * Set up GET /management/instances operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetManagementInstancesHandle * -TALER_MERCHANT_get_management_instances_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetManagementInstancesCallback. - */ -#define TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE */ - -/** - * Callback for a GET /management/instances request. - * - * @param cls closure - * @param igr response details - */ -typedef void -(*TALER_MERCHANT_GetManagementInstancesCallback)( - TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetManagementInstancesResponse *igr); - - -/** - * Start GET /management/instances operation. - * - * @param[in,out] gimh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_management_instances_start ( - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh, - TALER_MERCHANT_GetManagementInstancesCallback cb, - TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /management/instances operation. This function must not be - * called by clients after the TALER_MERCHANT_GetManagementInstancesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gimh operation to cancel - */ -void -TALER_MERCHANT_get_management_instances_cancel ( - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh); - - -#endif /* _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-management-instances.h b/src/include/taler/taler-merchant/get-management-instances.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-management-instances.h - * @brief C interface for GET /management/instances of the merchant backend + * @brief C interface for the GET /management/instances endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_H @@ -28,13 +28,13 @@ /** * Handle for a GET /management/instances request. */ -struct TALER_MERCHANT_InstancesGetHandle; +struct TALER_MERCHANT_GetManagementInstancesHandle; /** * Information about one merchant instance. */ -struct TALER_MERCHANT_InstanceInformation +struct TALER_MERCHANT_GetManagementInstancesInstanceInfo { /** @@ -63,7 +63,7 @@ struct TALER_MERCHANT_InstanceInformation /** * Response details for a GET /management/instances request. */ -struct TALER_MERCHANT_InstancesGetResponse +struct TALER_MERCHANT_GetManagementInstancesResponse { /** @@ -91,7 +91,7 @@ struct TALER_MERCHANT_InstancesGetResponse /** * Array of instance information. */ - const struct TALER_MERCHANT_InstanceInformation *iis; + const struct TALER_MERCHANT_GetManagementInstancesInstanceInfo *iis; } ok; @@ -101,42 +101,66 @@ struct TALER_MERCHANT_InstancesGetResponse /** + * Set up GET /management/instances operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetManagementInstancesHandle * +TALER_MERCHANT_get_management_instances_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetManagementInstancesCallback. + */ +#define TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE */ + +/** * Callback for a GET /management/instances request. * * @param cls closure * @param igr response details */ typedef void -(*TALER_MERCHANT_InstancesGetCallback)( - void *cls, - const struct TALER_MERCHANT_InstancesGetResponse *igr); +(*TALER_MERCHANT_GetManagementInstancesCallback)( + TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetManagementInstancesResponse *igr); /** - * Issue a GET /management/instances request. + * Start GET /management/instances operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instances_cb callback to invoke with the result - * @param instances_cb_cls closure for @a instances_cb - * @return handle for the request, NULL on hard error + * @param[in,out] gimh operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_InstancesGetHandle * -TALER_MERCHANT_instances_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_InstancesGetCallback instances_cb, - void *instances_cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_management_instances_start ( + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh, + TALER_MERCHANT_GetManagementInstancesCallback cb, + TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /management/instances request. + * Cancel GET /management/instances operation. This function must not be + * called by clients after the TALER_MERCHANT_GetManagementInstancesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] igh handle to cancel + * @param[in] gimh operation to cancel */ void -TALER_MERCHANT_instances_get_cancel ( - struct TALER_MERCHANT_InstancesGetHandle *igh); +TALER_MERCHANT_get_management_instances_cancel ( + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh); -#endif +#endif /* _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_H */ diff --git a/src/include/taler/taler-merchant/get-orders-ORDER_ID-new.h b/src/include/taler/taler-merchant/get-orders-ORDER_ID-new.h @@ -1,356 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-orders-ORDER_ID-new.h - * @brief C interface for the GET /orders/$ORDER_ID endpoint (wallet-facing) - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_ORDERS_ORDER_ID_NEW_H -#define _TALER_MERCHANT__GET_ORDERS_ORDER_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /orders/$ORDER_ID request. - */ -enum TALER_MERCHANT_GetOrdersOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_ORDERS_OPTION_END = 0, - - /** - * Long polling timeout. - */ - TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT, - - /** - * Session ID for repurchase detection. - */ - TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID, - - /** - * Minimum refund amount to wait for. - */ - TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND, - - /** - * If true, wait until refund is confirmed obtained. - */ - TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED - -}; - - -/** - * Value for an option for the GET /orders/$ORDER_ID request. - */ -struct TALER_MERCHANT_GetOrdersOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetOrdersOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID. - */ - const char *session_id; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND. - */ - struct TALER_Amount min_refund; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED. - */ - bool await_refund_obtained; - - } details; - -}; - - -/** - * Handle for a GET /orders/$ORDER_ID request (wallet-facing). - */ -struct TALER_MERCHANT_GetOrdersHandle; - - -/** - * Set up GET /orders/$ORDER_ID operation (wallet-facing). - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to check - * @param h_contract hash of the contract terms (for authentication) - * @return handle to operation - */ -struct TALER_MERCHANT_GetOrdersHandle * -TALER_MERCHANT_get_orders_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetOrdersOptionValue - */ -#define TALER_MERCHANT_get_orders_option_end_() \ - (const struct TALER_MERCHANT_GetOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_ORDERS_OPTION_END \ - } - -/** - * Set long polling timeout. - * - * @param t timeout to use - * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue - */ -#define TALER_MERCHANT_get_orders_option_timeout(t) \ - (const struct TALER_MERCHANT_GetOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT, \ - .details.timeout = (t) \ - } - -/** - * Set session ID for repurchase detection. - * - * @param s session ID to use - * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue - */ -#define TALER_MERCHANT_get_orders_option_session_id(s) \ - (const struct TALER_MERCHANT_GetOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID, \ - .details.session_id = (s) \ - } - -/** - * Set minimum refund amount to wait for. - * - * @param a minimum refund amount - * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue - */ -#define TALER_MERCHANT_get_orders_option_min_refund(a) \ - (const struct TALER_MERCHANT_GetOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND, \ - .details.min_refund = (a) \ - } - -/** - * Set await refund obtained flag. - * - * @param b true to wait until refund is confirmed obtained - * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue - */ -#define TALER_MERCHANT_get_orders_option_await_refund_obtained(b) \ - (const struct TALER_MERCHANT_GetOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED, \ - .details.await_refund_obtained = (b) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param oph 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_orders_set_options_ ( - struct TALER_MERCHANT_GetOrdersHandle *oph, - unsigned int num_options, - const struct TALER_MERCHANT_GetOrdersOptionValue *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_orders_set_options ( - * oph, - * TALER_MERCHANT_get_orders_option_timeout ( - * GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)), - * TALER_MERCHANT_get_orders_option_session_id ("mysession")); - * - * @param oph the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_orders_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_orders_set_options(oph,...) \ - TALER_MERCHANT_get_orders_set_options_ ( \ - oph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetOrdersOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_get_orders_option_end_ () } \ - )) - - -/** - * Response details for a GET /orders/$ORDER_ID request (wallet-facing). - */ -struct TALER_MERCHANT_GetOrdersResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK (order is paid, refund info available). - */ - struct - { - - /** - * True if a refund has been granted. - */ - bool refunded; - - /** - * True if a refund is still pending. - */ - bool refund_pending; - - /** - * Total amount refunded. - */ - struct TALER_Amount refund_amount; - - } ok; - - /** - * Details on #MHD_HTTP_PAYMENT_REQUIRED (order not yet paid). - */ - struct - { - - /** - * Taler pay URI for this order. - */ - const char *taler_pay_uri; - - /** - * Order ID of a previously paid order that covers this one, - * or NULL if none. - */ - const char *already_paid_order_id; - - } payment_required; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetOrdersCallback. - */ -#define TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE */ - -/** - * Callback for a GET /orders/$ORDER_ID request (wallet-facing). - * - * @param cls closure - * @param owgr response details - */ -typedef void -(*TALER_MERCHANT_GetOrdersCallback)( - TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetOrdersResponse *owgr); - - -/** - * Start GET /orders/$ORDER_ID operation (wallet-facing). - * - * @param[in,out] oph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_orders_start ( - struct TALER_MERCHANT_GetOrdersHandle *oph, - TALER_MERCHANT_GetOrdersCallback cb, - TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /orders/$ORDER_ID operation (wallet-facing). This function - * must not be called by clients after the TALER_MERCHANT_GetOrdersCallback - * has been invoked (as in those cases it'll be called internally by - * the implementation already). - * - * @param[in] oph operation to cancel - */ -void -TALER_MERCHANT_get_orders_cancel ( - struct TALER_MERCHANT_GetOrdersHandle *oph); - - -#endif /* _TALER_MERCHANT__GET_ORDERS_ORDER_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-orders-ORDER_ID.h b/src/include/taler/taler-merchant/get-orders-ORDER_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-orders-ORDER_ID.h - * @brief C interface for GET /orders/$ORDER_ID (wallet-facing) of the merchant backend + * @brief C interface for the GET /orders/$ORDER_ID endpoint (wallet-facing) * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_ORDERS_ORDER_ID_H @@ -26,15 +26,225 @@ /** + * Possible options we can set for the GET /orders/$ORDER_ID request. + */ +enum TALER_MERCHANT_GetOrdersOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_ORDERS_OPTION_END = 0, + + /** + * Long polling timeout. + */ + TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT, + + /** + * Session ID for repurchase detection. + */ + TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID, + + /** + * Minimum refund amount to wait for. + */ + TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND, + + /** + * If true, wait until refund is confirmed obtained. + */ + TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED + +}; + + +/** + * Value for an option for the GET /orders/$ORDER_ID request. + */ +struct TALER_MERCHANT_GetOrdersOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetOrdersOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT. + */ + struct GNUNET_TIME_Relative timeout; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID. + */ + const char *session_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND. + */ + struct TALER_Amount min_refund; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED. + */ + bool await_refund_obtained; + + } details; + +}; + + +/** * Handle for a GET /orders/$ORDER_ID request (wallet-facing). */ -struct TALER_MERCHANT_OrderWalletGetHandle; +struct TALER_MERCHANT_GetOrdersHandle; + + +/** + * Set up GET /orders/$ORDER_ID operation (wallet-facing). + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order to check + * @param h_contract hash of the contract terms (for authentication) + * @return handle to operation + */ +struct TALER_MERCHANT_GetOrdersHandle * +TALER_MERCHANT_get_orders_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct TALER_PrivateContractHashP *h_contract); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetOrdersOptionValue + */ +#define TALER_MERCHANT_get_orders_option_end_() \ + (const struct TALER_MERCHANT_GetOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_ORDERS_OPTION_END \ + } + +/** + * Set long polling timeout. + * + * @param t timeout to use + * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue + */ +#define TALER_MERCHANT_get_orders_option_timeout(t) \ + (const struct TALER_MERCHANT_GetOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT, \ + .details.timeout = (t) \ + } + +/** + * Set session ID for repurchase detection. + * + * @param s session ID to use + * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue + */ +#define TALER_MERCHANT_get_orders_option_session_id(s) \ + (const struct TALER_MERCHANT_GetOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID, \ + .details.session_id = (s) \ + } + +/** + * Set minimum refund amount to wait for. + * + * @param a minimum refund amount + * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue + */ +#define TALER_MERCHANT_get_orders_option_min_refund(a) \ + (const struct TALER_MERCHANT_GetOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND, \ + .details.min_refund = (a) \ + } + +/** + * Set await refund obtained flag. + * + * @param b true to wait until refund is confirmed obtained + * @return representation of the option as a struct TALER_MERCHANT_GetOrdersOptionValue + */ +#define TALER_MERCHANT_get_orders_option_await_refund_obtained(b) \ + (const struct TALER_MERCHANT_GetOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED, \ + .details.await_refund_obtained = (b) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param oph 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_orders_set_options_ ( + struct TALER_MERCHANT_GetOrdersHandle *oph, + unsigned int num_options, + const struct TALER_MERCHANT_GetOrdersOptionValue *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_orders_set_options ( + * oph, + * TALER_MERCHANT_get_orders_option_timeout ( + * GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)), + * TALER_MERCHANT_get_orders_option_session_id ("mysession")); + * + * @param oph the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_orders_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_orders_set_options(oph,...) \ + TALER_MERCHANT_get_orders_set_options_ ( \ + oph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetOrdersOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_get_orders_option_end_ () } \ + )) /** * Response details for a GET /orders/$ORDER_ID request (wallet-facing). */ -struct TALER_MERCHANT_OrderWalletGetResponse +struct TALER_MERCHANT_GetOrdersResponse { /** @@ -95,6 +305,14 @@ struct TALER_MERCHANT_OrderWalletGetResponse }; +#ifndef TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetOrdersCallback. + */ +#define TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE */ + /** * Callback for a GET /orders/$ORDER_ID request (wallet-facing). * @@ -102,48 +320,37 @@ struct TALER_MERCHANT_OrderWalletGetResponse * @param owgr response details */ typedef void -(*TALER_MERCHANT_OrderWalletGetCallback)( - void *cls, - const struct TALER_MERCHANT_OrderWalletGetResponse *owgr); +(*TALER_MERCHANT_GetOrdersCallback)( + TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetOrdersResponse *owgr); /** - * Issue a GET /orders/$ORDER_ID request (wallet-facing). + * Start GET /orders/$ORDER_ID operation (wallet-facing). * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order_id identifier of the order to check - * @param h_contract hash of the contract terms (to verify), or NULL - * @param timeout long-polling timeout - * @param session_id session identifier for repurchase, or NULL - * @param min_refund minimum refund amount to wait for, or NULL - * @param await_refund_obtained if true, wait until refund is confirmed obtained - * @param cb callback to invoke with the result + * @param[in,out] oph operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderWalletGetHandle * -TALER_MERCHANT_wallet_order_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract, - struct GNUNET_TIME_Relative timeout, - const char *session_id, - const struct TALER_Amount *min_refund, - bool await_refund_obtained, - TALER_MERCHANT_OrderWalletGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_orders_start ( + struct TALER_MERCHANT_GetOrdersHandle *oph, + TALER_MERCHANT_GetOrdersCallback cb, + TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /orders/$ORDER_ID request (wallet-facing). + * Cancel GET /orders/$ORDER_ID operation (wallet-facing). This function + * must not be called by clients after the TALER_MERCHANT_GetOrdersCallback + * has been invoked (as in those cases it'll be called internally by + * the implementation already). * - * @param[in] owgh handle to cancel + * @param[in] oph operation to cancel */ void -TALER_MERCHANT_wallet_order_get_cancel ( - struct TALER_MERCHANT_OrderWalletGetHandle *owgh); +TALER_MERCHANT_get_orders_cancel ( + struct TALER_MERCHANT_GetOrdersHandle *oph); -#endif +#endif /* _TALER_MERCHANT__GET_ORDERS_ORDER_ID_H */ diff --git a/src/include/taler/taler-merchant/get-private-accounts-H_WIRE-new.h b/src/include/taler/taler-merchant/get-private-accounts-H_WIRE-new.h @@ -1,171 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-accounts-H_WIRE-new.h - * @brief C interface for GET /private/accounts/$H_WIRE of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_H_WIRE_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_H_WIRE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/accounts/$H_WIRE request. - */ -struct TALER_MERCHANT_GetPrivateAccountHandle; - - -/** - * Account details for a merchant wire account. - */ -struct TALER_MERCHANT_GetPrivateAccountDetails -{ - - /** - * Hash of the wire details. - */ - struct TALER_MerchantWireHashP h_wire; - - /** - * Salt used in the wire hash computation. - */ - struct TALER_WireSaltP salt; - - /** - * Full payto URI of the account. - */ - struct TALER_FullPayto payto_uri; - - /** - * URL of the credit facade, or NULL if none. - */ - const char *credit_facade_url; - - /** - * True if the account is currently active. - */ - bool active; - -}; - - -/** - * Response details for a GET /private/accounts/$H_WIRE request. - */ -struct TALER_MERCHANT_GetPrivateAccountResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Detailed account information. - */ - struct TALER_MERCHANT_GetPrivateAccountDetails ad; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/accounts/$H_WIRE operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param instance_id identifier of the merchant instance - * @param h_wire hash of the wire details identifying the account - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateAccountHandle * -TALER_MERCHANT_get_private_account_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - const struct TALER_MerchantWireHashP *h_wire); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateAccountCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/accounts/$H_WIRE request. - * - * @param cls closure - * @param agr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateAccountCallback)( - TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateAccountResponse *agr); - - -/** - * Start GET /private/accounts/$H_WIRE operation. - * - * @param[in,out] gpa operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_account_start ( - struct TALER_MERCHANT_GetPrivateAccountHandle *gpa, - TALER_MERCHANT_GetPrivateAccountCallback cb, - TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/accounts/$H_WIRE operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateAccountCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpa operation to cancel - */ -void -TALER_MERCHANT_get_private_account_cancel ( - struct TALER_MERCHANT_GetPrivateAccountHandle *gpa); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_H_WIRE_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-accounts-H_WIRE.h b/src/include/taler/taler-merchant/get-private-accounts-H_WIRE.h @@ -28,13 +28,13 @@ /** * Handle for a GET /private/accounts/$H_WIRE request. */ -struct TALER_MERCHANT_AccountGetHandle; +struct TALER_MERCHANT_GetPrivateAccountHandle; /** * Account details for a merchant wire account. */ -struct TALER_MERCHANT_AccountDetails +struct TALER_MERCHANT_GetPrivateAccountDetails { /** @@ -68,7 +68,7 @@ struct TALER_MERCHANT_AccountDetails /** * Response details for a GET /private/accounts/$H_WIRE request. */ -struct TALER_MERCHANT_AccountGetResponse +struct TALER_MERCHANT_GetPrivateAccountResponse { /** @@ -91,7 +91,7 @@ struct TALER_MERCHANT_AccountGetResponse /** * Detailed account information. */ - struct TALER_MERCHANT_AccountDetails ad; + struct TALER_MERCHANT_GetPrivateAccountDetails ad; } ok; @@ -101,45 +101,71 @@ struct TALER_MERCHANT_AccountGetResponse /** + * Set up GET /private/accounts/$H_WIRE operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param instance_id identifier of the merchant instance + * @param h_wire hash of the wire details identifying the account + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateAccountHandle * +TALER_MERCHANT_get_private_account_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id, + const struct TALER_MerchantWireHashP *h_wire); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateAccountCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE */ + +/** * Callback for a GET /private/accounts/$H_WIRE request. * * @param cls closure * @param agr response details */ typedef void -(*TALER_MERCHANT_AccountGetCallback)( - void *cls, - const struct TALER_MERCHANT_AccountGetResponse *agr); +(*TALER_MERCHANT_GetPrivateAccountCallback)( + TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateAccountResponse *agr); /** - * Issue a GET /private/accounts/$H_WIRE request. + * Start GET /private/accounts/$H_WIRE operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the merchant instance - * @param h_wire hash of the wire details identifying the account - * @param cb callback to invoke with the result + * @param[in,out] gpa operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_AccountGetHandle * -TALER_MERCHANT_account_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - const struct TALER_MerchantWireHashP *h_wire, - TALER_MERCHANT_AccountGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_account_start ( + struct TALER_MERCHANT_GetPrivateAccountHandle *gpa, + TALER_MERCHANT_GetPrivateAccountCallback cb, + TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/accounts/$H_WIRE request. + * Cancel GET /private/accounts/$H_WIRE operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateAccountCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] gpa operation to cancel */ void -TALER_MERCHANT_account_get_cancel ( - struct TALER_MERCHANT_AccountGetHandle *tgh); +TALER_MERCHANT_get_private_account_cancel ( + struct TALER_MERCHANT_GetPrivateAccountHandle *gpa); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_H_WIRE_H */ diff --git a/src/include/taler/taler-merchant/get-private-accounts-new.h b/src/include/taler/taler-merchant/get-private-accounts-new.h @@ -1,156 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-accounts-new.h - * @brief C interface for the GET /private/accounts endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/accounts request. - */ -struct TALER_MERCHANT_GetPrivateAccountsHandle; - - -/** - * Account details for a merchant wire account. - */ -struct TALER_MERCHANT_GetPrivateAccountsAccountEntry -{ - - /** - * Hash of the wire details. - */ - struct TALER_MerchantWireHashP h_wire; - - /** - * Full payto URI of the account. - */ - struct TALER_FullPayto payto_uri; - -}; - - -/** - * Response details for a GET /private/accounts request. - */ -struct TALER_MERCHANT_GetPrivateAccountsResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of accounts in @a accounts. - */ - unsigned int accounts_length; - - /** - * Array of account entries. - */ - const struct TALER_MERCHANT_GetPrivateAccountsAccountEntry *accounts; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/accounts operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateAccountsHandle * -TALER_MERCHANT_get_private_accounts_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateAccountsCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/accounts request. - * - * @param cls closure - * @param agr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateAccountsCallback)( - TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateAccountsResponse *agr); - - -/** - * Start GET /private/accounts operation. - * - * @param[in,out] gpah operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_accounts_start ( - struct TALER_MERCHANT_GetPrivateAccountsHandle *gpah, - TALER_MERCHANT_GetPrivateAccountsCallback cb, - TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/accounts operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateAccountsCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpah operation to cancel - */ -void -TALER_MERCHANT_get_private_accounts_cancel ( - struct TALER_MERCHANT_GetPrivateAccountsHandle *gpah); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-accounts.h b/src/include/taler/taler-merchant/get-private-accounts.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-accounts.h - * @brief C interface for GET /private/accounts of the merchant backend + * @brief C interface for the GET /private/accounts endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_H @@ -28,13 +28,13 @@ /** * Handle for a GET /private/accounts request. */ -struct TALER_MERCHANT_AccountsGetHandle; +struct TALER_MERCHANT_GetPrivateAccountsHandle; /** * Account details for a merchant wire account. */ -struct TALER_MERCHANT_AccountEntry +struct TALER_MERCHANT_GetPrivateAccountsAccountEntry { /** @@ -47,14 +47,13 @@ struct TALER_MERCHANT_AccountEntry */ struct TALER_FullPayto payto_uri; - }; /** * Response details for a GET /private/accounts request. */ -struct TALER_MERCHANT_AccountsGetResponse +struct TALER_MERCHANT_GetPrivateAccountsResponse { /** @@ -82,7 +81,7 @@ struct TALER_MERCHANT_AccountsGetResponse /** * Array of account entries. */ - const struct TALER_MERCHANT_AccountEntry *accounts; + const struct TALER_MERCHANT_GetPrivateAccountsAccountEntry *accounts; } ok; @@ -92,41 +91,66 @@ struct TALER_MERCHANT_AccountsGetResponse /** + * Set up GET /private/accounts operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateAccountsHandle * +TALER_MERCHANT_get_private_accounts_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateAccountsCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE */ + +/** * Callback for a GET /private/accounts request. * * @param cls closure * @param agr response details */ typedef void -(*TALER_MERCHANT_AccountsGetCallback)( - void *cls, - const struct TALER_MERCHANT_AccountsGetResponse *agr); +(*TALER_MERCHANT_GetPrivateAccountsCallback)( + TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateAccountsResponse *agr); /** - * Issue a GET /private/accounts request. + * Start GET /private/accounts operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpah operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_AccountsGetHandle * -TALER_MERCHANT_accounts_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_AccountsGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_accounts_start ( + struct TALER_MERCHANT_GetPrivateAccountsHandle *gpah, + TALER_MERCHANT_GetPrivateAccountsCallback cb, + TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/accounts request. + * Cancel GET /private/accounts operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateAccountsCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] gpah operation to cancel */ void -TALER_MERCHANT_accounts_get_cancel ( - struct TALER_MERCHANT_AccountsGetHandle *tgh); +TALER_MERCHANT_get_private_accounts_cancel ( + struct TALER_MERCHANT_GetPrivateAccountsHandle *gpah); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_ACCOUNTS_H */ diff --git a/src/include/taler/taler-merchant/get-private-donau-new.h b/src/include/taler/taler-merchant/get-private-donau-new.h @@ -1,191 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-donau-new.h - * @brief C interface for the GET /private/donau endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_DONAU_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_DONAU_NEW_H - -#include <taler/taler-merchant/common.h> -#include <donau/donau_service.h> - - -/** - * Handle for a GET /private/donau request. - */ -struct TALER_MERCHANT_GetPrivateDonauHandle; - - -/** - * Individual Donau instance details. - */ -struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry -{ - /** - * Serial number of the Donau instance in merchant database. - */ - uint64_t donau_instance_serial; - - /** - * The URL of the Donau service. - */ - const char *donau_url; - - /** - * Name of the charity associated with the Donau instance. - */ - const char *charity_name; - - /** - * Public key of the charity. - */ - struct DONAU_CharityPublicKeyP charity_pub_key; - - /** - * ID of the charity on Donau. - */ - uint64_t charity_id; - - /** - * Maximum donation amount per year allowed for the charity. - */ - struct TALER_Amount charity_max_per_year; - - /** - * Total donations received by the charity in the current year. - */ - struct TALER_Amount charity_receipts_to_date; - - /** - * The current year being tracked for donations. - */ - int64_t current_year; - - /** - * Additional key information related to the Donau instance. - */ - const struct DONAU_Keys *donau_keys; -}; - - -/** - * Response details for a GET /private/donau request. - */ -struct TALER_MERCHANT_GetPrivateDonauResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of Donau instances in @a donau_instances. - */ - unsigned int donau_instances_length; - - /** - * Array of Donau instance entries. - */ - const struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry * - donau_instances; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/donau operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateDonauHandle * -TALER_MERCHANT_get_private_donau_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateDonauCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/donau request. - * - * @param cls closure - * @param dgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateDonauCallback)( - TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateDonauResponse *dgr); - - -/** - * Start GET /private/donau operation. - * - * @param[in,out] gpdh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_donau_start ( - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh, - TALER_MERCHANT_GetPrivateDonauCallback cb, - TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/donau operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateDonauCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpdh operation to cancel - */ -void -TALER_MERCHANT_get_private_donau_cancel ( - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_DONAU_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-donau.h b/src/include/taler/taler-merchant/get-private-donau.h @@ -16,25 +16,26 @@ */ /** * @file include/taler/taler-merchant/get-private-donau.h - * @brief C interface for GET /private/donau of the merchant backend + * @brief C interface for the GET /private/donau endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_DONAU_H #define _TALER_MERCHANT__GET_PRIVATE_DONAU_H #include <taler/taler-merchant/common.h> +#include <donau/donau_service.h> /** * Handle for a GET /private/donau request. */ -struct TALER_MERCHANT_DonauInstanceGetHandle; +struct TALER_MERCHANT_GetPrivateDonauHandle; /** * Individual Donau instance details. */ -struct TALER_MERCHANT_DonauInstanceEntry +struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry { /** * Serial number of the Donau instance in merchant database. @@ -86,7 +87,7 @@ struct TALER_MERCHANT_DonauInstanceEntry /** * Response details for a GET /private/donau request. */ -struct TALER_MERCHANT_DonauInstanceGetResponse +struct TALER_MERCHANT_GetPrivateDonauResponse { /** @@ -114,7 +115,8 @@ struct TALER_MERCHANT_DonauInstanceGetResponse /** * Array of Donau instance entries. */ - const struct TALER_MERCHANT_DonauInstanceEntry *donau_instances; + const struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry * + donau_instances; } ok; @@ -124,42 +126,66 @@ struct TALER_MERCHANT_DonauInstanceGetResponse /** + * Set up GET /private/donau operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateDonauHandle * +TALER_MERCHANT_get_private_donau_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateDonauCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE */ + +/** * Callback for a GET /private/donau request. * * @param cls closure - * @param igr response details + * @param dgr response details */ typedef void -(*TALER_MERCHANT_DonauInstanceGetCallback)( - void *cls, - const struct TALER_MERCHANT_DonauInstanceGetResponse *igr); +(*TALER_MERCHANT_GetPrivateDonauCallback)( + TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateDonauResponse *dgr); /** - * Issue a GET /private/donau request to list registered Donau instances. + * Start GET /private/donau operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpdh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_DonauInstanceGetHandle * -TALER_MERCHANT_donau_instances_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_DonauInstanceGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_donau_start ( + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh, + TALER_MERCHANT_GetPrivateDonauCallback cb, + TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/donau request. + * Cancel GET /private/donau operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateDonauCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] dgh handle to cancel + * @param[in] gpdh operation to cancel */ void -TALER_MERCHANT_donau_instances_get_cancel ( - struct TALER_MERCHANT_DonauInstanceGetHandle *dgh); +TALER_MERCHANT_get_private_donau_cancel ( + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_DONAU_H */ diff --git a/src/include/taler/taler-merchant/get-private-kyc-new.h b/src/include/taler/taler-merchant/get-private-kyc-new.h @@ -1,443 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-kyc-new.h - * @brief C interface for the GET /private/kyc (and /management/instances/$INSTANCE/kyc) endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_KYC_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_KYC_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /private/kyc request. - */ -enum TALER_MERCHANT_GetPrivateKycOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END = 0, - - /** - * Hash of the wire account to check, or NULL for all. - */ - TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE, - - /** - * URL of the exchange to check with, or NULL for any. - */ - TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL, - - /** - * Long-poll target (what status to wait for). - */ - TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT, - - /** - * Long polling timeout. - */ - TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT, - - /** - * 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 - -}; - - -/** - * Value for an option for the GET /private/kyc request. - */ -struct TALER_MERCHANT_GetPrivateKycOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetPrivateKycOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE. - */ - const struct TALER_MerchantWireHashP *h_wire; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL. - */ - const char *exchange_url; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT. - */ - enum TALER_EXCHANGE_KycLongPollTarget lpt; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID. - * If set, the management endpoint - * /management/instances/$INSTANCE/kyc is used instead of - * /private/kyc. - */ - const char *instance_id; - - } details; - -}; - - -/** - * Handle for a GET /private/kyc (or /management/instances/$INSTANCE/kyc) request. - */ -struct TALER_MERCHANT_GetPrivateKycHandle; - - -/** - * Set up GET /private/kyc operation. - * Note that you must explicitly start the operation after - * possibly setting options. By default, uses the /private/kyc - * endpoint; set the INSTANCE_ID option to use the management - * endpoint instead. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateKycHandle * -TALER_MERCHANT_get_private_kyc_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetPrivateKycOptionValue - */ -#define TALER_MERCHANT_get_private_kyc_option_end_() \ - (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END \ - } - -/** - * Set hash of the wire account to check. - * - * @param h pointer to the wire hash to filter by - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue - */ -#define TALER_MERCHANT_get_private_kyc_option_h_wire(h) \ - (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE, \ - .details.h_wire = (h) \ - } - -/** - * Set exchange URL to check with. - * - * @param u exchange URL to filter by - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue - */ -#define TALER_MERCHANT_get_private_kyc_option_exchange_url(u) \ - (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL, \ - .details.exchange_url = (u) \ - } - -/** - * Set long-poll target. - * - * @param t long-poll target to wait for - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue - */ -#define TALER_MERCHANT_get_private_kyc_option_lpt(t) \ - (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT, \ - .details.lpt = (t) \ - } - -/** - * Set long polling timeout. - * - * @param t timeout to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue - */ -#define TALER_MERCHANT_get_private_kyc_option_timeout(t) \ - (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT, \ - .details.timeout = (t) \ - } - -/** - * Set instance ID for management mode. When set, the request uses - * the /management/instances/$INSTANCE/kyc endpoint instead of - * /private/kyc. - * - * @param id instance identifier - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue - */ -#define TALER_MERCHANT_get_private_kyc_option_instance_id(id) \ - (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID, \ - .details.instance_id = (id) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param kyc 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_kyc_set_options_ ( - struct TALER_MERCHANT_GetPrivateKycHandle *kyc, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateKycOptionValue *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_kyc_set_options ( - * kyc, - * TALER_MERCHANT_get_private_kyc_option_exchange_url ( - * "https://exchange.example.com/"), - * TALER_MERCHANT_get_private_kyc_option_timeout ( - * GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30))); - * - * @param kyc the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_private_kyc_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_private_kyc_set_options(kyc,...) \ - TALER_MERCHANT_get_private_kyc_set_options_ ( \ - kyc, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetPrivateKycOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_get_private_kyc_option_end_ () } \ - )) - - -/** - * Information about KYC actions the merchant still must perform. - */ -struct TALER_MERCHANT_GetPrivateKycRedirectDetail -{ - - /** - * Access token the user needs to start a KYC process, - * all zero if a KYC auth transfer must be made first. - */ - struct TALER_AccountAccessTokenP access_token; - - /** - * Base URL of the exchange this is about. - */ - const char *exchange_url; - - /** - * Our bank wire account this is about. - */ - struct TALER_FullPayto payto_uri; - - /** - * Array of length @e limits_length with (exposed) limits that apply to the - * account. - */ - const struct TALER_EXCHANGE_AccountLimit *limits; - - /** - * Array of payto://-URIs with instructions for wire - * transfers to perform a KYC auth wire transfer for - * the given account. Needed if @e access_token is zero - * and @e limits are to be passed. - */ - struct TALER_FullPayto *payto_kycauths; - - /** - * Length of the @e limits array. - */ - unsigned int limits_length; - - /** - * Length of the @e payto_kycauths array. - */ - unsigned int pkycauth_length; - - /** - * HTTP status code returned by the exchange when we asked for - * information about the KYC status. - * 0 if there was no response at all. - */ - unsigned int exchange_http_status; - - /** - * Error code indicating errors the exchange - * returned, or #TALER_EC_NONE for none. - */ - enum TALER_ErrorCode exchange_code; - - /** - * Set to true if @e access_token was not given. - */ - bool no_access_token; - - /** - * Set to true if the merchant backend could not - * get the exchanges ``/keys`` and thus could not - * determine default limits or determine an - * @e auth_conflict. - */ - bool no_keys; - - /** - * Set to true if the given account cannot do KYC at the given exchange - * because no wire method exists that could be used to do the KYC auth wire - * transfer. - */ - bool auth_conflict; - -}; - - -/** - * Response details for a KYC status request. - */ -struct TALER_MERCHANT_GetPrivateKycResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of KYC redirect details in @a kycs. - */ - unsigned int kycs_length; - - /** - * Array of KYC redirect details for accounts requiring KYC. - */ - const struct TALER_MERCHANT_GetPrivateKycRedirectDetail *kycs; - - } ok; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateKycCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE */ - -/** - * Callback for a KYC status request. - * - * @param cls closure - * @param kr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateKycCallback)( - TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateKycResponse *kr); - - -/** - * Start GET /private/kyc (or /management/instances/$INSTANCE/kyc) operation. - * - * @param[in,out] kyc operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_kyc_start ( - struct TALER_MERCHANT_GetPrivateKycHandle *kyc, - TALER_MERCHANT_GetPrivateKycCallback cb, - TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/kyc operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateKycCallback - * has been invoked (as in those cases it'll be called internally by - * the implementation already). - * - * @param[in] kyc operation to cancel - */ -void -TALER_MERCHANT_get_private_kyc_cancel ( - struct TALER_MERCHANT_GetPrivateKycHandle *kyc); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_KYC_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-kyc.h b/src/include/taler/taler-merchant/get-private-kyc.h @@ -15,26 +15,265 @@ <http://www.gnu.org/licenses/> */ /** - * @file include/taler/taler-merchant/get-management-instances-INSTANCE-kyc.h - * @brief C interface for GET /management/instances/$INSTANCE/kyc of the merchant backend + * @file include/taler/taler-merchant/get-private-kyc.h + * @brief C interface for the GET /private/kyc (and /management/instances/$INSTANCE/kyc) endpoint * @author Christian Grothoff */ -#ifndef _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_KYC_H -#define _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_KYC_H +#ifndef _TALER_MERCHANT__GET_PRIVATE_KYC_H +#define _TALER_MERCHANT__GET_PRIVATE_KYC_H #include <taler/taler-merchant/common.h> /** - * Handle for a GET /management/instances/$INSTANCE/kyc (or /private/kyc) request. + * Possible options we can set for the GET /private/kyc request. */ -struct TALER_MERCHANT_KycGetHandle; +enum TALER_MERCHANT_GetPrivateKycOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END = 0, + + /** + * Hash of the wire account to check, or NULL for all. + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE, + + /** + * URL of the exchange to check with, or NULL for any. + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL, + + /** + * Long-poll target (what status to wait for). + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT, + + /** + * Long polling timeout. + */ + TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT, + + /** + * 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 + +}; + + +/** + * Value for an option for the GET /private/kyc request. + */ +struct TALER_MERCHANT_GetPrivateKycOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateKycOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE. + */ + const struct TALER_MerchantWireHashP *h_wire; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL. + */ + const char *exchange_url; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT. + */ + enum TALER_EXCHANGE_KycLongPollTarget lpt; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT. + */ + struct GNUNET_TIME_Relative timeout; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID. + * If set, the management endpoint + * /management/instances/$INSTANCE/kyc is used instead of + * /private/kyc. + */ + const char *instance_id; + + } details; + +}; + + +/** + * Handle for a GET /private/kyc (or /management/instances/$INSTANCE/kyc) request. + */ +struct TALER_MERCHANT_GetPrivateKycHandle; + + +/** + * Set up GET /private/kyc operation. + * Note that you must explicitly start the operation after + * possibly setting options. By default, uses the /private/kyc + * endpoint; set the INSTANCE_ID option to use the management + * endpoint instead. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateKycHandle * +TALER_MERCHANT_get_private_kyc_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END \ + } + +/** + * Set hash of the wire account to check. + * + * @param h pointer to the wire hash to filter by + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_h_wire(h) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE, \ + .details.h_wire = (h) \ + } + +/** + * Set exchange URL to check with. + * + * @param u exchange URL to filter by + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_exchange_url(u) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL, \ + .details.exchange_url = (u) \ + } + +/** + * Set long-poll target. + * + * @param t long-poll target to wait for + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_lpt(t) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT, \ + .details.lpt = (t) \ + } + +/** + * Set long polling timeout. + * + * @param t timeout to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_timeout(t) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT, \ + .details.timeout = (t) \ + } + +/** + * Set instance ID for management mode. When set, the request uses + * the /management/instances/$INSTANCE/kyc endpoint instead of + * /private/kyc. + * + * @param id instance identifier + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateKycOptionValue + */ +#define TALER_MERCHANT_get_private_kyc_option_instance_id(id) \ + (const struct TALER_MERCHANT_GetPrivateKycOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID, \ + .details.instance_id = (id) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param kyc 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_kyc_set_options_ ( + struct TALER_MERCHANT_GetPrivateKycHandle *kyc, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateKycOptionValue *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_kyc_set_options ( + * kyc, + * TALER_MERCHANT_get_private_kyc_option_exchange_url ( + * "https://exchange.example.com/"), + * TALER_MERCHANT_get_private_kyc_option_timeout ( + * GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30))); + * + * @param kyc the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_kyc_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_kyc_set_options(kyc,...) \ + TALER_MERCHANT_get_private_kyc_set_options_ ( \ + kyc, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateKycOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_get_private_kyc_option_end_ () } \ + )) /** * Information about KYC actions the merchant still must perform. */ -struct TALER_MERCHANT_AccountKycRedirectDetail +struct TALER_MERCHANT_GetPrivateKycRedirectDetail { /** @@ -54,7 +293,7 @@ struct TALER_MERCHANT_AccountKycRedirectDetail struct TALER_FullPayto payto_uri; /** - * Array of length @e limits_array with (exposed) limits that apply to the + * Array of length @e limits_length with (exposed) limits that apply to the * account. */ const struct TALER_EXCHANGE_AccountLimit *limits; @@ -62,7 +301,7 @@ struct TALER_MERCHANT_AccountKycRedirectDetail /** * Array of payto://-URIs with instructions for wire * transfers to perform a KYC auth wire transfer for - * the given account. Needed if @e kyc_url is NULL + * the given account. Needed if @e access_token is zero * and @e limits are to be passed. */ struct TALER_FullPayto *payto_kycauths; @@ -104,18 +343,19 @@ struct TALER_MERCHANT_AccountKycRedirectDetail bool no_keys; /** - * Set to true if the given account cannot to KYC at the given exchange + * Set to true if the given account cannot do KYC at the given exchange * because no wire method exists that could be used to do the KYC auth wire * transfer. */ bool auth_conflict; + }; /** * Response details for a KYC status request. */ -struct TALER_MERCHANT_KycResponse +struct TALER_MERCHANT_GetPrivateKycResponse { /** @@ -130,7 +370,7 @@ struct TALER_MERCHANT_KycResponse { /** - * Details on #MHD_HTTP_OK (all accounts passed KYC). + * Details on #MHD_HTTP_OK. */ struct { @@ -143,7 +383,7 @@ struct TALER_MERCHANT_KycResponse /** * Array of KYC redirect details for accounts requiring KYC. */ - const struct TALER_MERCHANT_AccountKycRedirectDetail *kycs; + const struct TALER_MERCHANT_GetPrivateKycRedirectDetail *kycs; } ok; @@ -152,6 +392,14 @@ struct TALER_MERCHANT_KycResponse }; +#ifndef TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateKycCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE */ + /** * Callback for a KYC status request. * @@ -159,73 +407,37 @@ struct TALER_MERCHANT_KycResponse * @param kr response details */ typedef void -(*TALER_MERCHANT_KycGetCallback)( - void *cls, - const struct TALER_MERCHANT_KycResponse *kr); +(*TALER_MERCHANT_GetPrivateKycCallback)( + TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateKycResponse *kr); /** - * Issue a GET /private/kyc request to check KYC status for accounts - * of the current instance. + * Start GET /private/kyc (or /management/instances/$INSTANCE/kyc) operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param h_wire hash of the wire account to check, or NULL for all - * @param exchange_url URL of the exchange to check with, or NULL for any - * @param lpt long-poll target (what status to wait for) - * @param timeout long-polling timeout - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error - */ -struct TALER_MERCHANT_KycGetHandle * -TALER_MERCHANT_kyc_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MerchantWireHashP *h_wire, - const char *exchange_url, - enum TALER_EXCHANGE_KycLongPollTarget lpt, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_KycGetCallback cb, - void *cb_cls); - - -/** - * Issue a GET /management/instances/$INSTANCE/kyc request to check KYC - * status for accounts of a specific instance (management access required). - * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the instance to check - * @param h_wire hash of the wire account to check, or NULL for all - * @param exchange_url URL of the exchange to check with, or NULL for any - * @param lpt long-poll target (what status to wait for) - * @param timeout long-polling timeout - * @param cb callback to invoke with the result + * @param[in,out] kyc operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_KycGetHandle * -TALER_MERCHANT_management_kyc_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - const struct TALER_MerchantWireHashP *h_wire, - const char *exchange_url, - enum TALER_EXCHANGE_KycLongPollTarget lpt, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_KycGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_kyc_start ( + struct TALER_MERCHANT_GetPrivateKycHandle *kyc, + TALER_MERCHANT_GetPrivateKycCallback cb, + TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls); /** - * Cancel a KYC status request. + * Cancel GET /private/kyc operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateKycCallback + * has been invoked (as in those cases it'll be called internally by + * the implementation already). * - * @param[in] kyc handle to cancel + * @param[in] kyc operation to cancel */ void -TALER_MERCHANT_kyc_get_cancel ( - struct TALER_MERCHANT_KycGetHandle *kyc); +TALER_MERCHANT_get_private_kyc_cancel ( + struct TALER_MERCHANT_GetPrivateKycHandle *kyc); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_KYC_H */ diff --git a/src/include/taler/taler-merchant/get-private-orders-ORDER_ID-new.h b/src/include/taler/taler-merchant/get-private-orders-ORDER_ID-new.h @@ -1,449 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-orders-ORDER_ID-new.h - * @brief C interface for the GET /private/orders/$ORDER_ID endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_ORDERS_ORDER_ID_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_ORDERS_ORDER_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /private/orders/$ORDER_ID request. - */ -enum TALER_MERCHANT_GetPrivateOrderOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END = 0, - - /** - * Session ID for repurchase detection. - */ - TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID, - - /** - * Long polling timeout. - */ - TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT - -}; - - -/** - * Value for an option for the GET /private/orders/$ORDER_ID request. - */ -struct TALER_MERCHANT_GetPrivateOrderOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetPrivateOrderOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID. - */ - const char *session_id; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT. - */ - struct GNUNET_TIME_Relative timeout; - - } details; - -}; - - -/** - * Handle for a GET /private/orders/$ORDER_ID request. - */ -struct TALER_MERCHANT_GetPrivateOrderHandle; - - -/** - * Set up GET /private/orders/$ORDER_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateOrderHandle * -TALER_MERCHANT_get_private_order_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetPrivateOrderOptionValue - */ -#define TALER_MERCHANT_get_private_order_option_end_() \ - (const struct TALER_MERCHANT_GetPrivateOrderOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END \ - } - -/** - * Set session ID for repurchase detection. - * - * @param s session ID to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrderOptionValue - */ -#define TALER_MERCHANT_get_private_order_option_session_id(s) \ - (const struct TALER_MERCHANT_GetPrivateOrderOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID, \ - .details.session_id = (s) \ - } - -/** - * Set long polling timeout. - * - * @param t timeout to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrderOptionValue - */ -#define TALER_MERCHANT_get_private_order_option_timeout(t) \ - (const struct TALER_MERCHANT_GetPrivateOrderOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT, \ - .details.timeout = (t) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param oph 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_order_set_options_ ( - struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateOrderOptionValue *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_order_set_options ( - * oph, - * TALER_MERCHANT_get_private_order_option_session_id ("mysession")); - * - * @param oph the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_private_order_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_private_order_set_options(oph,...) \ - TALER_MERCHANT_get_private_order_set_options_ ( \ - oph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetPrivateOrderOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_get_private_order_option_end_ () } \ - )) - - -/** - * Order status code. - */ -enum TALER_MERCHANT_OrderStatusCode -{ - /** - * The order is unpaid. - */ - TALER_MERCHANT_OSC_UNPAID = 0, - - /** - * The order has been claimed by a wallet. - */ - TALER_MERCHANT_OSC_CLAIMED = 1, - - /** - * The order has been paid. - */ - TALER_MERCHANT_OSC_PAID = 2 -}; - - -/** - * Refund detail in a paid order (merchant view). - */ -struct TALER_MERCHANT_GetPrivateOrderRefundDetail -{ - - /** - * Human-readable reason given for the refund. - */ - const char *reason; - - /** - * Time when the refund was granted. - */ - struct GNUNET_TIME_Timestamp refund_time; - - /** - * Total amount that was refunded. - */ - struct TALER_Amount refund_amount; - -}; - - -/** - * Response details for a GET /private/orders/$ORDER_ID request. - */ -struct TALER_MERCHANT_GetPrivateOrderResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Current status of the order. - */ - enum TALER_MERCHANT_OrderStatusCode status; - - /** - * Details depending on @a status. - */ - union - { - - /** - * Details when @a status is #TALER_MERCHANT_OSC_UNPAID. - */ - struct - { - - /** - * Total amount of the order. - */ - struct TALER_Amount contract_amount; - - /** - * Order ID of a previously paid order that covers this one, - * or NULL if none. - */ - const char *already_paid_order_id; - - /** - * Taler pay URI for this order. - */ - const char *taler_pay_uri; - - /** - * Short summary of the order. - */ - const char *summary; - - /** - * Timestamp when the order was created. - */ - struct GNUNET_TIME_Timestamp creation_time; - - } unpaid; - - /** - * Details when @a status is #TALER_MERCHANT_OSC_CLAIMED. - */ - struct - { - - /** - * Contract terms (JSON). - */ - const json_t *contract_terms; - - } claimed; - - /** - * Details when @a status is #TALER_MERCHANT_OSC_PAID. - */ - struct - { - - /** - * True if a refund has been granted. - */ - bool refunded; - - /** - * True if a refund is still pending at the exchange. - */ - bool refund_pending; - - /** - * True if the payment has been wired to the merchant. - */ - bool wired; - - /** - * Total amount deposited. - */ - struct TALER_Amount deposit_total; - - /** - * Error code from the exchange, or TALER_EC_NONE. - */ - enum TALER_ErrorCode exchange_ec; - - /** - * HTTP status returned by the exchange. - */ - unsigned int exchange_hc; - - /** - * Total amount refunded. - */ - struct TALER_Amount refund_amount; - - /** - * Contract terms (JSON). - */ - const json_t *contract_terms; - - /** - * Number of wire transfers in @a wts. - */ - unsigned int wts_len; - - /** - * Array of wire transfer details. - */ - struct TALER_MERCHANT_WireTransfer *wts; - - /** - * Number of refund details in @a refunds. - */ - unsigned int refunds_len; - - /** - * Array of per-coin refund details. - */ - struct TALER_MERCHANT_GetPrivateOrderRefundDetail *refunds; - - /** - * Timestamp of the last payment. - */ - struct GNUNET_TIME_Timestamp last_payment; - - } paid; - - } details; - - } ok; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateOrderCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/orders/$ORDER_ID request. - * - * @param cls closure - * @param osr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateOrderCallback)( - TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateOrderResponse *osr); - - -/** - * Start GET /private/orders/$ORDER_ID operation. - * - * @param[in,out] oph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_order_start ( - struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - TALER_MERCHANT_GetPrivateOrderCallback cb, - TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/orders/$ORDER_ID operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateOrderCallback - * has been invoked (as in those cases it'll be called internally by - * the implementation already). - * - * @param[in] oph operation to cancel - */ -void -TALER_MERCHANT_get_private_order_cancel ( - struct TALER_MERCHANT_GetPrivateOrderHandle *oph); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_ORDERS_ORDER_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-orders-ORDER_ID.h b/src/include/taler/taler-merchant/get-private-orders-ORDER_ID.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-orders-ORDER_ID.h - * @brief C interface for GET /private/orders/$ORDER_ID of the merchant backend + * @brief C interface for the GET /private/orders/$ORDER_ID endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_ORDERS_ORDER_ID_H @@ -26,9 +26,167 @@ /** + * Possible options we can set for the GET /private/orders/$ORDER_ID request. + */ +enum TALER_MERCHANT_GetPrivateOrderOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END = 0, + + /** + * Session ID for repurchase detection. + */ + TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID, + + /** + * Long polling timeout. + */ + TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT + +}; + + +/** + * Value for an option for the GET /private/orders/$ORDER_ID request. + */ +struct TALER_MERCHANT_GetPrivateOrderOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateOrderOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID. + */ + const char *session_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT. + */ + struct GNUNET_TIME_Relative timeout; + + } details; + +}; + + +/** * Handle for a GET /private/orders/$ORDER_ID request. */ -struct TALER_MERCHANT_OrderMerchantGetHandle; +struct TALER_MERCHANT_GetPrivateOrderHandle; + + +/** + * Set up GET /private/orders/$ORDER_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateOrderHandle * +TALER_MERCHANT_get_private_order_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateOrderOptionValue + */ +#define TALER_MERCHANT_get_private_order_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateOrderOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END \ + } + +/** + * Set session ID for repurchase detection. + * + * @param s session ID to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrderOptionValue + */ +#define TALER_MERCHANT_get_private_order_option_session_id(s) \ + (const struct TALER_MERCHANT_GetPrivateOrderOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID, \ + .details.session_id = (s) \ + } + +/** + * Set long polling timeout. + * + * @param t timeout to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrderOptionValue + */ +#define TALER_MERCHANT_get_private_order_option_timeout(t) \ + (const struct TALER_MERCHANT_GetPrivateOrderOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT, \ + .details.timeout = (t) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param oph 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_order_set_options_ ( + struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateOrderOptionValue *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_order_set_options ( + * oph, + * TALER_MERCHANT_get_private_order_option_session_id ("mysession")); + * + * @param oph the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_order_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_order_set_options(oph,...) \ + TALER_MERCHANT_get_private_order_set_options_ ( \ + oph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateOrderOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_get_private_order_option_end_ () } \ + )) /** @@ -56,7 +214,7 @@ enum TALER_MERCHANT_OrderStatusCode /** * Refund detail in a paid order (merchant view). */ -struct TALER_MERCHANT_RefundOrderDetail +struct TALER_MERCHANT_GetPrivateOrderRefundDetail { /** @@ -80,7 +238,7 @@ struct TALER_MERCHANT_RefundOrderDetail /** * Response details for a GET /private/orders/$ORDER_ID request. */ -struct TALER_MERCHANT_OrderStatusResponse +struct TALER_MERCHANT_GetPrivateOrderResponse { /** @@ -222,7 +380,7 @@ struct TALER_MERCHANT_OrderStatusResponse /** * Array of per-coin refund details. */ - struct TALER_MERCHANT_RefundOrderDetail *refunds; + struct TALER_MERCHANT_GetPrivateOrderRefundDetail *refunds; /** * Timestamp of the last payment. @@ -240,6 +398,14 @@ struct TALER_MERCHANT_OrderStatusResponse }; +#ifndef TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateOrderCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE */ + /** * Callback for a GET /private/orders/$ORDER_ID request. * @@ -247,42 +413,37 @@ struct TALER_MERCHANT_OrderStatusResponse * @param osr response details */ typedef void -(*TALER_MERCHANT_OrderMerchantGetCallback)( - void *cls, - const struct TALER_MERCHANT_OrderStatusResponse *osr); +(*TALER_MERCHANT_GetPrivateOrderCallback)( + TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateOrderResponse *osr); /** - * Issue a GET /private/orders/$ORDER_ID request. + * Start GET /private/orders/$ORDER_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order_id identifier of the order to retrieve - * @param session_id session ID for repurchase detection, or NULL - * @param timeout long-polling timeout - * @param cb callback to invoke with the result + * @param[in,out] oph operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderMerchantGetHandle * -TALER_MERCHANT_merchant_order_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const char *session_id, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_OrderMerchantGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_order_start ( + struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + TALER_MERCHANT_GetPrivateOrderCallback cb, + TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/orders/$ORDER_ID request. + * Cancel GET /private/orders/$ORDER_ID operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateOrderCallback + * has been invoked (as in those cases it'll be called internally by + * the implementation already). * - * @param[in] omgh handle to cancel + * @param[in] oph operation to cancel */ void -TALER_MERCHANT_merchant_order_get_cancel ( - struct TALER_MERCHANT_OrderMerchantGetHandle *omgh); +TALER_MERCHANT_get_private_order_cancel ( + struct TALER_MERCHANT_GetPrivateOrderHandle *oph); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_ORDERS_ORDER_ID_H */ diff --git a/src/include/taler/taler-merchant/get-private-orders-new.h b/src/include/taler/taler-merchant/get-private-orders-new.h @@ -1,528 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-orders-new.h - * @brief C interface for the GET /private/orders endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_ORDERS_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_ORDERS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /private/orders request. - */ -enum TALER_MERCHANT_GetPrivateOrdersOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_END = 0, - - /** - * Filter by paid status. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID, - - /** - * Filter by refunded status. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED, - - /** - * Filter by wired status. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED, - - /** - * Return at most N values. Negative values - * to return before offset, positive to return after offset. - * Default is -20. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT, - - /** - * Starting row_id for pagination. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET, - - /** - * Date threshold for filtering. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE, - - /** - * Long polling timeout. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT, - - /** - * Filter by session ID. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID, - - /** - * Filter by fulfillment URL. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL, - - /** - * Filter by summary text (case-insensitive substring match). - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER - -}; - - -/** - * Value for an option for the GET /private/orders request. - */ -struct TALER_MERCHANT_GetPrivateOrdersOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetPrivateOrdersOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID. - */ - enum TALER_EXCHANGE_YesNoAll paid; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED. - */ - enum TALER_EXCHANGE_YesNoAll refunded; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED. - */ - enum TALER_EXCHANGE_YesNoAll wired; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT. - */ - int64_t limit; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET. - */ - uint64_t offset; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE. - */ - struct GNUNET_TIME_Timestamp date; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID. - */ - const char *session_id; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL. - */ - const char *fulfillment_url; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER. - */ - const char *summary_filter; - - } details; - -}; - - -/** - * Handle for a GET /private/orders request. - */ -struct TALER_MERCHANT_GetPrivateOrdersHandle; - - -/** - * Set up GET /private/orders operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateOrdersHandle * -TALER_MERCHANT_get_private_orders_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_end_() \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_END \ - } - -/** - * Set filter on paid status. - * - * @param p paid filter to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_paid(p) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID, \ - .details.paid = (p) \ - } - -/** - * Set filter on refunded status. - * - * @param r refunded filter to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_refunded(r) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED, \ - .details.refunded = (r) \ - } - -/** - * Set filter on wired status. - * - * @param w wired filter to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_wired(w) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED, \ - .details.wired = (w) \ - } - -/** - * Set limit on the number of results to return. - * - * @param l limit on the number of results to return - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_limit(l) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT, \ - .details.limit = (l) \ - } - -/** - * Set row offset from which to return results. - * - * @param o offset to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_offset(o) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET, \ - .details.offset = (o) \ - } - -/** - * Set date threshold for filtering. - * - * @param d date threshold to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_date(d) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE, \ - .details.date = (d) \ - } - -/** - * Set long polling timeout. - * - * @param t timeout to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_timeout(t) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT, \ - .details.timeout = (t) \ - } - -/** - * Set session ID filter. - * - * @param s session ID to filter by - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_session_id(s) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID, \ - .details.session_id = (s) \ - } - -/** - * Set fulfillment URL filter. - * - * @param u fulfillment URL to filter by - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_fulfillment_url(u) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL, \ - .details.fulfillment_url = (u) \ - } - -/** - * Set summary text filter. - * - * @param f summary filter string (case-insensitive substring match) - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue - */ -#define TALER_MERCHANT_get_private_orders_option_summary_filter(f) \ - (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER, \ - .details.summary_filter = (f) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param oph 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_orders_set_options_ ( - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateOrdersOptionValue *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_orders_set_options ( - * oph, - * TALER_MERCHANT_get_private_orders_option_paid ( - * TALER_EXCHANGE_YNA_YES), - * TALER_MERCHANT_get_private_orders_option_limit (-20)); - * - * @param oph the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_private_orders_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_private_orders_set_options(oph,...) \ - TALER_MERCHANT_get_private_orders_set_options_ ( \ - oph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetPrivateOrdersOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_get_private_orders_option_end_ () } \ - )) - - -/** - * Entry for one order in the GET /private/orders response. - */ -struct TALER_MERCHANT_GetPrivateOrdersOrderEntry -{ - - /** - * The order identifier string. - */ - const char *order_id; - - /** - * Timestamp when the order was created. - */ - struct GNUNET_TIME_Timestamp timestamp; - - /** - * Serial number of the order in the database. - */ - uint64_t order_serial; - - /** - * Total amount of the order. - */ - struct TALER_Amount amount; - - /** - * Amount refunded so far. - */ - struct TALER_Amount refund_amount; - - /** - * Amount still pending refund. - */ - struct TALER_Amount pending_refund_amount; - - /** - * Short summary of the order. - */ - const char *summary; - - /** - * True if refund is possible. - */ - bool refundable; - - /** - * True if the order has been paid. - */ - bool paid; - -}; - - -/** - * Response details for a GET /private/orders request. - */ -struct TALER_MERCHANT_GetPrivateOrdersResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of orders in @a orders. - */ - unsigned int orders_length; - - /** - * Array of order entries. - */ - const struct TALER_MERCHANT_GetPrivateOrdersOrderEntry *orders; - - } ok; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateOrdersCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/orders request. - * - * @param cls closure - * @param ogr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateOrdersCallback)( - TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateOrdersResponse *ogr); - - -/** - * Start GET /private/orders operation. - * - * @param[in,out] oph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_orders_start ( - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, - TALER_MERCHANT_GetPrivateOrdersCallback cb, - TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/orders operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateOrdersCallback - * has been invoked (as in those cases it'll be called internally by - * the implementation already). - * - * @param[in] oph operation to cancel - */ -void -TALER_MERCHANT_get_private_orders_cancel ( - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_ORDERS_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-orders.h b/src/include/taler/taler-merchant/get-private-orders.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-orders.h - * @brief C interface for GET /private/orders of the merchant backend + * @brief C interface for the GET /private/orders endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_ORDERS_H @@ -26,15 +26,367 @@ /** + * Possible options we can set for the GET /private/orders request. + */ +enum TALER_MERCHANT_GetPrivateOrdersOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_END = 0, + + /** + * Filter by paid status. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID, + + /** + * Filter by refunded status. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED, + + /** + * Filter by wired status. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED, + + /** + * Return at most N values. Negative values + * to return before offset, positive to return after offset. + * Default is -20. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT, + + /** + * Starting row_id for pagination. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET, + + /** + * Date threshold for filtering. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE, + + /** + * Long polling timeout. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT, + + /** + * Filter by session ID. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID, + + /** + * Filter by fulfillment URL. + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL, + + /** + * Filter by summary text (case-insensitive substring match). + */ + TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER + +}; + + +/** + * Value for an option for the GET /private/orders request. + */ +struct TALER_MERCHANT_GetPrivateOrdersOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateOrdersOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID. + */ + enum TALER_EXCHANGE_YesNoAll paid; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED. + */ + enum TALER_EXCHANGE_YesNoAll refunded; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED. + */ + enum TALER_EXCHANGE_YesNoAll wired; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT. + */ + int64_t limit; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET. + */ + uint64_t offset; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE. + */ + struct GNUNET_TIME_Timestamp date; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT. + */ + struct GNUNET_TIME_Relative timeout; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID. + */ + const char *session_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL. + */ + const char *fulfillment_url; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER. + */ + const char *summary_filter; + + } details; + +}; + + +/** * Handle for a GET /private/orders request. */ -struct TALER_MERCHANT_OrdersGetHandle; +struct TALER_MERCHANT_GetPrivateOrdersHandle; + + +/** + * Set up GET /private/orders operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateOrdersHandle * +TALER_MERCHANT_get_private_orders_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_END \ + } + +/** + * Set filter on paid status. + * + * @param p paid filter to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_paid(p) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID, \ + .details.paid = (p) \ + } + +/** + * Set filter on refunded status. + * + * @param r refunded filter to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_refunded(r) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED, \ + .details.refunded = (r) \ + } + +/** + * Set filter on wired status. + * + * @param w wired filter to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_wired(w) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED, \ + .details.wired = (w) \ + } + +/** + * Set limit on the number of results to return. + * + * @param l limit on the number of results to return + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_limit(l) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT, \ + .details.limit = (l) \ + } + +/** + * Set row offset from which to return results. + * + * @param o offset to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_offset(o) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET, \ + .details.offset = (o) \ + } + +/** + * Set date threshold for filtering. + * + * @param d date threshold to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_date(d) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE, \ + .details.date = (d) \ + } + +/** + * Set long polling timeout. + * + * @param t timeout to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_timeout(t) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT, \ + .details.timeout = (t) \ + } + +/** + * Set session ID filter. + * + * @param s session ID to filter by + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_session_id(s) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID, \ + .details.session_id = (s) \ + } + +/** + * Set fulfillment URL filter. + * + * @param u fulfillment URL to filter by + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_fulfillment_url(u) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL, \ + .details.fulfillment_url = (u) \ + } + +/** + * Set summary text filter. + * + * @param f summary filter string (case-insensitive substring match) + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateOrdersOptionValue + */ +#define TALER_MERCHANT_get_private_orders_option_summary_filter(f) \ + (const struct TALER_MERCHANT_GetPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER, \ + .details.summary_filter = (f) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param oph 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_orders_set_options_ ( + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateOrdersOptionValue *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_orders_set_options ( + * oph, + * TALER_MERCHANT_get_private_orders_option_paid ( + * TALER_EXCHANGE_YNA_YES), + * TALER_MERCHANT_get_private_orders_option_limit (-20)); + * + * @param oph the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_orders_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_orders_set_options(oph,...) \ + TALER_MERCHANT_get_private_orders_set_options_ ( \ + oph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateOrdersOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_get_private_orders_option_end_ () } \ + )) /** * Entry for one order in the GET /private/orders response. */ -struct TALER_MERCHANT_OrderEntry +struct TALER_MERCHANT_GetPrivateOrdersOrderEntry { /** @@ -88,7 +440,7 @@ struct TALER_MERCHANT_OrderEntry /** * Response details for a GET /private/orders request. */ -struct TALER_MERCHANT_OrdersGetResponse +struct TALER_MERCHANT_GetPrivateOrdersResponse { /** @@ -116,7 +468,7 @@ struct TALER_MERCHANT_OrdersGetResponse /** * Array of order entries. */ - const struct TALER_MERCHANT_OrderEntry *orders; + const struct TALER_MERCHANT_GetPrivateOrdersOrderEntry *orders; } ok; @@ -125,6 +477,14 @@ struct TALER_MERCHANT_OrdersGetResponse }; +#ifndef TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateOrdersCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE */ + /** * Callback for a GET /private/orders request. * @@ -132,102 +492,37 @@ struct TALER_MERCHANT_OrdersGetResponse * @param ogr response details */ typedef void -(*TALER_MERCHANT_OrdersGetCallback)( - void *cls, - const struct TALER_MERCHANT_OrdersGetResponse *ogr); +(*TALER_MERCHANT_GetPrivateOrdersCallback)( + TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateOrdersResponse *ogr); /** - * Issue a GET /private/orders request (simple form). + * Start GET /private/orders operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] oph operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrdersGetHandle * -TALER_MERCHANT_orders_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_OrdersGetCallback cb, - void *cb_cls); - - -/** - * Issue a GET /private/orders request with filters. - * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param paid filter by paid status - * @param refunded filter by refunded status - * @param wired filter by wired status - * @param date date to use for pagination - * @param start_row row to start from - * @param delta number of results to return (negative for backwards) - * @param timeout long-polling timeout - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error - */ -struct TALER_MERCHANT_OrdersGetHandle * -TALER_MERCHANT_orders_get2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - enum TALER_EXCHANGE_YesNoAll paid, - enum TALER_EXCHANGE_YesNoAll refunded, - enum TALER_EXCHANGE_YesNoAll wired, - struct GNUNET_TIME_Timestamp date, - uint64_t start_row, - int64_t delta, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_OrdersGetCallback cb, - void *cb_cls); - - -/** - * Issue a GET /private/orders request with extended filters including - * session and fulfillment URL filtering. - * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param paid filter by paid status - * @param refunded filter by refunded status - * @param wired filter by wired status - * @param session_id filter by session ID, or NULL - * @param fulfillment_url filter by fulfillment URL, or NULL - * @param date date to use for pagination - * @param start_row row to start from - * @param delta number of results to return (negative for backwards) - * @param timeout long-polling timeout - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error - */ -struct TALER_MERCHANT_OrdersGetHandle * -TALER_MERCHANT_orders_get3 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - enum TALER_EXCHANGE_YesNoAll paid, - enum TALER_EXCHANGE_YesNoAll refunded, - enum TALER_EXCHANGE_YesNoAll wired, - const char *session_id, - const char *fulfillment_url, - struct GNUNET_TIME_Timestamp date, - uint64_t start_row, - int64_t delta, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_OrdersGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_orders_start ( + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, + TALER_MERCHANT_GetPrivateOrdersCallback cb, + TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/orders request. + * Cancel GET /private/orders operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateOrdersCallback + * has been invoked (as in those cases it'll be called internally by + * the implementation already). * - * @param[in] ogh handle to cancel + * @param[in] oph operation to cancel */ void -TALER_MERCHANT_orders_get_cancel ( - struct TALER_MERCHANT_OrdersGetHandle *ogh); +TALER_MERCHANT_get_private_orders_cancel ( + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_ORDERS_H */ diff --git a/src/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h b/src/include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h @@ -1,160 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h - * @brief C interface for GET /private/otp-devices/$DEVICE_ID of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/otp-devices/$DEVICE_ID request. - */ -struct TALER_MERCHANT_GetPrivateOtpDeviceHandle; - - -/** - * Response details for a GET /private/otp-devices/$DEVICE_ID request. - */ -struct TALER_MERCHANT_GetPrivateOtpDeviceResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Human-readable description of the OTP device. - */ - const char *otp_device_description; - - /** - * Current counter value of the OTP device (for HOTP). - */ - uint64_t otp_ctr; - - /** - * Current timestamp in seconds (for TOTP). - */ - uint64_t otp_timestamp_s; - - /** - * POS confirmation text with OTP codes that - * would be returned for a purchase over the - * amount given in the query for the respective - * time and algorithm. NULL if the confirmation - * could not be computed based on the query and - * OTP algorithm. - */ - const char *otp_code; - - /** - * OTP algorithm used. - */ - enum TALER_MerchantConfirmationAlgorithm otp_alg; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/otp-devices/$DEVICE_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param otp_device_id identifier of the OTP device to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateOtpDeviceHandle * -TALER_MERCHANT_get_private_otp_device_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateOtpDeviceCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/otp-devices/$DEVICE_ID request. - * - * @param cls closure - * @param ogr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateOtpDeviceCallback)( - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateOtpDeviceResponse *ogr); - - -/** - * Start GET /private/otp-devices/$DEVICE_ID operation. - * - * @param[in,out] god operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_otp_device_start ( - struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, - TALER_MERCHANT_GetPrivateOtpDeviceCallback cb, - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/otp-devices/$DEVICE_ID operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateOtpDeviceCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] god operation to cancel - */ -void -TALER_MERCHANT_get_private_otp_device_cancel ( - struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H */ 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 @@ -28,13 +28,13 @@ /** * Handle for a GET /private/otp-devices/$DEVICE_ID request. */ -struct TALER_MERCHANT_OtpDeviceGetHandle; +struct TALER_MERCHANT_GetPrivateOtpDeviceHandle; /** * Response details for a GET /private/otp-devices/$DEVICE_ID request. */ -struct TALER_MERCHANT_OtpDeviceGetResponse +struct TALER_MERCHANT_GetPrivateOtpDeviceResponse { /** @@ -92,43 +92,69 @@ struct TALER_MERCHANT_OtpDeviceGetResponse /** + * Set up GET /private/otp-devices/$DEVICE_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param otp_device_id identifier of the OTP device to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateOtpDeviceHandle * +TALER_MERCHANT_get_private_otp_device_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *otp_device_id); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateOtpDeviceCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE */ + +/** * Callback for a GET /private/otp-devices/$DEVICE_ID request. * * @param cls closure * @param ogr response details */ typedef void -(*TALER_MERCHANT_OtpDeviceGetCallback)( - void *cls, - const struct TALER_MERCHANT_OtpDeviceGetResponse *ogr); +(*TALER_MERCHANT_GetPrivateOtpDeviceCallback)( + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateOtpDeviceResponse *ogr); /** - * Issue a GET /private/otp-devices/$DEVICE_ID request. + * Start GET /private/otp-devices/$DEVICE_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param otp_device_id identifier of the OTP device to retrieve - * @param cb callback to invoke with the result + * @param[in,out] god operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OtpDeviceGetHandle * -TALER_MERCHANT_otp_device_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *otp_device_id, - TALER_MERCHANT_OtpDeviceGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_otp_device_start ( + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, + TALER_MERCHANT_GetPrivateOtpDeviceCallback cb, + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/otp-devices/$DEVICE_ID request. + * Cancel GET /private/otp-devices/$DEVICE_ID operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateOtpDeviceCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] god operation to cancel */ void -TALER_MERCHANT_otp_device_get_cancel ( - struct TALER_MERCHANT_OtpDeviceGetHandle *tgh); +TALER_MERCHANT_get_private_otp_device_cancel ( + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_DEVICE_ID_H */ diff --git a/src/include/taler/taler-merchant/get-private-otp-devices-new.h b/src/include/taler/taler-merchant/get-private-otp-devices-new.h @@ -1,157 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-otp-devices-new.h - * @brief C interface for the GET /private/otp-devices endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/otp-devices request. - */ -struct TALER_MERCHANT_GetPrivateOtpDevicesHandle; - - -/** - * Entry for one OTP device. - */ -struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry -{ - - /** - * Identifier of the OTP device. - */ - const char *otp_device_id; - - /** - * Human-readable description of the OTP device. - */ - const char *otp_device_description; - -}; - - -/** - * Response details for a GET /private/otp-devices request. - */ -struct TALER_MERCHANT_GetPrivateOtpDevicesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of OTP devices in @a otp_devices. - */ - unsigned int otp_devices_length; - - /** - * Array of OTP device entries. - */ - const struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry * - otp_devices; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/otp-devices operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateOtpDevicesHandle * -TALER_MERCHANT_get_private_otp_devices_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateOtpDevicesCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/otp-devices request. - * - * @param cls closure - * @param ogr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateOtpDevicesCallback)( - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateOtpDevicesResponse *ogr); - - -/** - * Start GET /private/otp-devices operation. - * - * @param[in,out] gpoh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_otp_devices_start ( - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh, - TALER_MERCHANT_GetPrivateOtpDevicesCallback cb, - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/otp-devices operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateOtpDevicesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpoh operation to cancel - */ -void -TALER_MERCHANT_get_private_otp_devices_cancel ( - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-otp-devices.h b/src/include/taler/taler-merchant/get-private-otp-devices.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-otp-devices.h - * @brief C interface for GET /private/otp-devices of the merchant backend + * @brief C interface for the GET /private/otp-devices endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_H @@ -28,13 +28,13 @@ /** * Handle for a GET /private/otp-devices request. */ -struct TALER_MERCHANT_OtpDevicesGetHandle; +struct TALER_MERCHANT_GetPrivateOtpDevicesHandle; /** * Entry for one OTP device. */ -struct TALER_MERCHANT_OtpDeviceEntry +struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry { /** @@ -53,7 +53,7 @@ struct TALER_MERCHANT_OtpDeviceEntry /** * Response details for a GET /private/otp-devices request. */ -struct TALER_MERCHANT_OtpDevicesGetResponse +struct TALER_MERCHANT_GetPrivateOtpDevicesResponse { /** @@ -81,7 +81,8 @@ struct TALER_MERCHANT_OtpDevicesGetResponse /** * Array of OTP device entries. */ - const struct TALER_MERCHANT_OtpDeviceEntry *otp_devices; + const struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry * + otp_devices; } ok; @@ -91,41 +92,66 @@ struct TALER_MERCHANT_OtpDevicesGetResponse /** + * Set up GET /private/otp-devices operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateOtpDevicesHandle * +TALER_MERCHANT_get_private_otp_devices_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateOtpDevicesCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE */ + +/** * Callback for a GET /private/otp-devices request. * * @param cls closure * @param ogr response details */ typedef void -(*TALER_MERCHANT_OtpDevicesGetCallback)( - void *cls, - const struct TALER_MERCHANT_OtpDevicesGetResponse *ogr); +(*TALER_MERCHANT_GetPrivateOtpDevicesCallback)( + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateOtpDevicesResponse *ogr); /** - * Issue a GET /private/otp-devices request. + * Start GET /private/otp-devices operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpoh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OtpDevicesGetHandle * -TALER_MERCHANT_otp_devices_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_OtpDevicesGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_otp_devices_start ( + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh, + TALER_MERCHANT_GetPrivateOtpDevicesCallback cb, + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/otp-devices request. + * Cancel GET /private/otp-devices operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateOtpDevicesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] gpoh operation to cancel */ void -TALER_MERCHANT_otp_devices_get_cancel ( - struct TALER_MERCHANT_OtpDevicesGetHandle *tgh); +TALER_MERCHANT_get_private_otp_devices_cancel ( + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_OTP_DEVICES_H */ diff --git a/src/include/taler/taler-merchant/get-private-products-PRODUCT_ID-new.h b/src/include/taler/taler-merchant/get-private-products-PRODUCT_ID-new.h @@ -1,216 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-products-PRODUCT_ID-new.h - * @brief C interface for GET /private/products/$PRODUCT_ID of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/products/$PRODUCT_ID request. - */ -struct TALER_MERCHANT_GetPrivateProductHandle; - - -/** - * Response details for a GET /private/products/$PRODUCT_ID request. - */ -struct TALER_MERCHANT_GetPrivateProductResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Human-readable product name. - */ - const char *product_name; - - /** - * Human-readable product description. - */ - const char *description; - - /** - * Internationalized descriptions (JSON object), or NULL. - */ - const json_t *description_i18n; - - /** - * Unit of measurement for this product. - */ - const char *unit; - - /** - * Number of prices in @a unit_price. - */ - size_t unit_price_len; - - /** - * Array of unit prices (for different payment options). - */ - const struct TALER_Amount *unit_price; - - /** - * Single unit price (first element of @a unit_price, for backwards compatibility). - */ - struct TALER_Amount price; - - /** - * Base64-encoded product image, or empty string. - */ - const char *image; - - /** - * Tax information (JSON array), or NULL. - */ - const json_t *taxes; - - /** - * Total available stock (-1 for unlimited). - */ - int64_t total_stock; - - /** - * Total stock in fractional unit representation. - * Stock level encoded as a decimal string. Preferred source of truth for fractional stock. - */ - const char *unit_total_stock; - - /** - * Whether fractional quantities are allowed. - */ - bool unit_allow_fraction; - - /** - * Precision level for fractional quantities. - */ - uint32_t unit_precision_level; - - /** - * Total number of units sold. - */ - uint64_t total_sold; - - /** - * Total number of units lost/expired. - */ - uint64_t total_lost; - - /** - * Storage location (JSON), or NULL. - */ - const json_t *location; - - /** - * Expected time of next restock (may be zero if unknown). - */ - struct GNUNET_TIME_Timestamp next_restock; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/products/$PRODUCT_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param product_id identifier of the product to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateProductHandle * -TALER_MERCHANT_get_private_product_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateProductCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/products/$PRODUCT_ID request. - * - * @param cls closure - * @param pgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateProductCallback)( - TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateProductResponse *pgr); - - -/** - * Start GET /private/products/$PRODUCT_ID operation. - * - * @param[in,out] gpp operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_product_start ( - struct TALER_MERCHANT_GetPrivateProductHandle *gpp, - TALER_MERCHANT_GetPrivateProductCallback cb, - TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/products/$PRODUCT_ID operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateProductCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpp operation to cancel - */ -void -TALER_MERCHANT_get_private_product_cancel ( - struct TALER_MERCHANT_GetPrivateProductHandle *gpp); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-products-PRODUCT_ID.h b/src/include/taler/taler-merchant/get-private-products-PRODUCT_ID.h @@ -28,13 +28,13 @@ /** * Handle for a GET /private/products/$PRODUCT_ID request. */ -struct TALER_MERCHANT_ProductGetHandle; +struct TALER_MERCHANT_GetPrivateProductHandle; /** * Response details for a GET /private/products/$PRODUCT_ID request. */ -struct TALER_MERCHANT_ProductGetResponse +struct TALER_MERCHANT_GetPrivateProductResponse { /** @@ -148,43 +148,69 @@ struct TALER_MERCHANT_ProductGetResponse /** + * Set up GET /private/products/$PRODUCT_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param product_id identifier of the product to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateProductHandle * +TALER_MERCHANT_get_private_product_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *product_id); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateProductCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE */ + +/** * Callback for a GET /private/products/$PRODUCT_ID request. * * @param cls closure * @param pgr response details */ typedef void -(*TALER_MERCHANT_ProductGetCallback)( - void *cls, - const struct TALER_MERCHANT_ProductGetResponse *pgr); +(*TALER_MERCHANT_GetPrivateProductCallback)( + TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateProductResponse *pgr); /** - * Issue a GET /private/products/$PRODUCT_ID request. + * Start GET /private/products/$PRODUCT_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param product_id identifier of the product to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gpp operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductGetHandle * -TALER_MERCHANT_product_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - TALER_MERCHANT_ProductGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_product_start ( + struct TALER_MERCHANT_GetPrivateProductHandle *gpp, + TALER_MERCHANT_GetPrivateProductCallback cb, + TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/products/$PRODUCT_ID request. + * Cancel GET /private/products/$PRODUCT_ID operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateProductCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] pgh handle to cancel + * @param[in] gpp operation to cancel */ void -TALER_MERCHANT_product_get_cancel ( - struct TALER_MERCHANT_ProductGetHandle *pgh); +TALER_MERCHANT_get_private_product_cancel ( + struct TALER_MERCHANT_GetPrivateProductHandle *gpp); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_PRODUCT_ID_H */ diff --git a/src/include/taler/taler-merchant/get-private-products-new.h b/src/include/taler/taler-merchant/get-private-products-new.h @@ -1,156 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-products-new.h - * @brief C interface for the GET /private/products endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/products request. - */ -struct TALER_MERCHANT_GetPrivateProductsHandle; - - -/** - * Inventory entry for the GET /private/products response. - */ -struct TALER_MERCHANT_GetPrivateProductsInventoryEntry -{ - - /** - * Identifier of the product. - */ - const char *product_id; - - /** - * Serial ID of the product. - */ - uint64_t product_serial; - -}; - - -/** - * Response details for a GET /private/products request. - */ -struct TALER_MERCHANT_GetPrivateProductsResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of products in @a products. - */ - unsigned int products_length; - - /** - * Array of product entries. - */ - const struct TALER_MERCHANT_GetPrivateProductsInventoryEntry *products; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/products operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateProductsHandle * -TALER_MERCHANT_get_private_products_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateProductsCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/products request. - * - * @param cls closure - * @param pgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateProductsCallback)( - TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateProductsResponse *pgr); - - -/** - * Start GET /private/products operation. - * - * @param[in,out] gpph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_products_start ( - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph, - TALER_MERCHANT_GetPrivateProductsCallback cb, - TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/products operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateProductsCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpph operation to cancel - */ -void -TALER_MERCHANT_get_private_products_cancel ( - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-products.h b/src/include/taler/taler-merchant/get-private-products.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-products.h - * @brief C interface for GET /private/products of the merchant backend + * @brief C interface for the GET /private/products endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_H @@ -28,12 +28,13 @@ /** * Handle for a GET /private/products request. */ -struct TALER_MERCHANT_ProductsGetHandle; +struct TALER_MERCHANT_GetPrivateProductsHandle; + /** * Inventory entry for the GET /private/products response. */ -struct TALER_MERCHANT_InventoryEntry +struct TALER_MERCHANT_GetPrivateProductsInventoryEntry { /** @@ -52,7 +53,7 @@ struct TALER_MERCHANT_InventoryEntry /** * Response details for a GET /private/products request. */ -struct TALER_MERCHANT_GetProductsResponse +struct TALER_MERCHANT_GetPrivateProductsResponse { /** @@ -80,7 +81,7 @@ struct TALER_MERCHANT_GetProductsResponse /** * Array of product entries. */ - const struct TALER_MERCHANT_InventoryEntry *products; + const struct TALER_MERCHANT_GetPrivateProductsInventoryEntry *products; } ok; @@ -90,41 +91,66 @@ struct TALER_MERCHANT_GetProductsResponse /** + * Set up GET /private/products operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateProductsHandle * +TALER_MERCHANT_get_private_products_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateProductsCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE */ + +/** * Callback for a GET /private/products request. * * @param cls closure * @param pgr response details */ typedef void -(*TALER_MERCHANT_ProductsGetCallback)( - void *cls, - const struct TALER_MERCHANT_GetProductsResponse *pgr); +(*TALER_MERCHANT_GetPrivateProductsCallback)( + TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateProductsResponse *pgr); /** - * Issue a GET /private/products request. + * Start GET /private/products operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpph operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductsGetHandle * -TALER_MERCHANT_products_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_ProductsGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_products_start ( + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph, + TALER_MERCHANT_GetPrivateProductsCallback cb, + TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/products request. + * Cancel GET /private/products operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateProductsCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] pgh handle to cancel + * @param[in] gpph operation to cancel */ void -TALER_MERCHANT_products_get_cancel ( - struct TALER_MERCHANT_ProductsGetHandle *pgh); +TALER_MERCHANT_get_private_products_cancel ( + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_PRODUCTS_H */ diff --git a/src/include/taler/taler-merchant/get-private-statistics-amount-SLUG-new.h b/src/include/taler/taler-merchant/get-private-statistics-amount-SLUG-new.h @@ -1,342 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-statistics-amount-SLUG-new.h - * @brief C interface for the GET /private/statistics-amount/$SLUG endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_STATISTICS_AMOUNT_SLUG_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_STATISTICS_AMOUNT_SLUG_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /private/statistics-amount/$SLUG request. - */ -enum TALER_MERCHANT_GetPrivateStatisticsAmountOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_END = 0, - - /** - * Aggregation mode to request (BUCKET, INTERVAL, or ANY). - */ - TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE - -}; - - -/** - * Value for an option for the GET /private/statistics-amount/$SLUG request. - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetPrivateStatisticsAmountOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE. - */ - enum TALER_MERCHANT_StatisticsType type; - - } details; - -}; - - -/** - * Handle for a GET /private/statistics-amount/$SLUG request. - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle; - - -/** - * Set up GET /private/statistics-amount/$SLUG operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param slug statistics slug to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle * -TALER_MERCHANT_get_private_statistics_amount_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *slug); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue - */ -#define TALER_MERCHANT_get_private_statistics_amount_option_end_() \ - (const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_END \ - } - -/** - * Set aggregation mode type. - * - * @param t aggregation mode to request - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue - */ -#define TALER_MERCHANT_get_private_statistics_amount_option_type(t) \ - (const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE, \ - .details.type = (t) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param sah 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_statistics_amount_set_options_ ( - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue *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_statistics_amount_set_options ( - * sah, - * TALER_MERCHANT_get_private_statistics_amount_option_type ( - * TALER_MERCHANT_STATISTICS_TYPE_BUCKET)); - * - * @param sah the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_private_statistics_amount_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_private_statistics_amount_set_options(sah,...) \ - TALER_MERCHANT_get_private_statistics_amount_set_options_ ( \ - sah, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue[]) \ - {__VA_ARGS__, \ - TALER_MERCHANT_get_private_statistics_amount_option_end_ () } \ - )) - - -/** - * Statistic amount aggregated by bucket. - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket -{ - - /** - * Start time of the bucket (inclusive). - */ - struct GNUNET_TIME_Timestamp start_time; - - /** - * End time of the bucket (exclusive). - */ - struct GNUNET_TIME_Timestamp end_time; - - /** - * Range of the bucket. - */ - const char *range; - - /** - * Sum of all amounts falling under the given - * SLUG within this timeframe. - */ - struct TALER_Amount *cumulative_amounts; - - /** - * Length of array @a cumulative_amounts. - */ - unsigned int cumulative_amount_len; - -}; - - -/** - * Statistic amount aggregated by interval. - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval -{ - - /** - * Start time of the interval (inclusive). - * The interval always ends at the response - * generation time. - */ - struct GNUNET_TIME_Timestamp start_time; - - /** - * Sum of all amounts falling under the given - * SLUG within this timeframe. - */ - struct TALER_Amount *cumulative_amounts; - - /** - * Length of array @a cumulative_amounts. - */ - unsigned int cumulative_amount_len; - -}; - - -/** - * Response details for a GET /private/statistics-amount/$SLUG request. - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of bucket entries in @a buckets. - */ - unsigned int buckets_length; - - /** - * Array of amount statistics per bucket. - */ - const struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket *buckets; - - /** - * Description of the bucket aggregation scheme, or NULL. - */ - const char *buckets_description; - - /** - * Number of interval entries in @a intervals. - */ - unsigned int intervals_length; - - /** - * Array of amount statistics per time interval. - */ - const struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval * - intervals; - - /** - * Description of the interval aggregation scheme, or NULL. - */ - const char *intervals_description; - - } ok; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateStatisticsAmountCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/statistics-amount/$SLUG request. - * - * @param cls closure - * @param sagr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateStatisticsAmountCallback)( - TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse *sagr); - - -/** - * Start GET /private/statistics-amount/$SLUG operation. - * - * @param[in,out] sah operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_statistics_amount_start ( - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, - TALER_MERCHANT_GetPrivateStatisticsAmountCallback cb, - TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/statistics-amount/$SLUG operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateStatisticsAmountCallback has been invoked - * (as in those cases it'll be called internally by the implementation - * already). - * - * @param[in] sah operation to cancel - */ -void -TALER_MERCHANT_get_private_statistics_amount_cancel ( - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_STATISTICS_AMOUNT_SLUG_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-statistics-amount-SLUG.h b/src/include/taler/taler-merchant/get-private-statistics-amount-SLUG.h @@ -15,23 +15,164 @@ <http://www.gnu.org/licenses/> */ /** - * @file include/taler/taler-merchant/get-management-instances-INSTANCE-statistics-amount-SLUG.h - * @brief C interface for GET .../statistics/amount/$SLUG of the merchant backend + * @file include/taler/taler-merchant/get-private-statistics-amount-SLUG.h + * @brief C interface for the GET /private/statistics-amount/$SLUG endpoint * @author Christian Grothoff */ -#ifndef \ - _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_STATISTICS_AMOUNT_SLUG_H -#define \ - _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_STATISTICS_AMOUNT_SLUG_H +#ifndef _TALER_MERCHANT__GET_PRIVATE_STATISTICS_AMOUNT_SLUG_H +#define _TALER_MERCHANT__GET_PRIVATE_STATISTICS_AMOUNT_SLUG_H #include <taler/taler-merchant/common.h> /** + * Possible options we can set for the GET /private/statistics-amount/$SLUG request. + */ +enum TALER_MERCHANT_GetPrivateStatisticsAmountOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_END = 0, + + /** + * Aggregation mode to request (BUCKET, INTERVAL, or ANY). + */ + TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE + +}; + + +/** + * Value for an option for the GET /private/statistics-amount/$SLUG request. + */ +struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateStatisticsAmountOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE. + */ + enum TALER_MERCHANT_StatisticsType type; + + } details; + +}; + + +/** + * Handle for a GET /private/statistics-amount/$SLUG request. + */ +struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle; + + +/** + * Set up GET /private/statistics-amount/$SLUG operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param slug statistics slug to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle * +TALER_MERCHANT_get_private_statistics_amount_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *slug); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue + */ +#define TALER_MERCHANT_get_private_statistics_amount_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_END \ + } + +/** + * Set aggregation mode type. + * + * @param t aggregation mode to request + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue + */ +#define TALER_MERCHANT_get_private_statistics_amount_option_type(t) \ + (const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE, \ + .details.type = (t) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param sah 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_statistics_amount_set_options_ ( + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue *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_statistics_amount_set_options ( + * sah, + * TALER_MERCHANT_get_private_statistics_amount_option_type ( + * TALER_MERCHANT_STATISTICS_TYPE_BUCKET)); + * + * @param sah the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_statistics_amount_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_statistics_amount_set_options(sah,...) \ + TALER_MERCHANT_get_private_statistics_amount_set_options_ ( \ + sah, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue[]) \ + {__VA_ARGS__, \ + TALER_MERCHANT_get_private_statistics_amount_option_end_ () } \ + )) + + +/** * Statistic amount aggregated by bucket. */ -struct TALER_MERCHANT_StatisticAmountByBucket +struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket { + /** * Start time of the bucket (inclusive). */ @@ -43,7 +184,7 @@ struct TALER_MERCHANT_StatisticAmountByBucket struct GNUNET_TIME_Timestamp end_time; /** - * Range of the bucket + * Range of the bucket. */ const char *range; @@ -54,17 +195,19 @@ struct TALER_MERCHANT_StatisticAmountByBucket struct TALER_Amount *cumulative_amounts; /** - * Length of array @a cumulative_amounts + * Length of array @a cumulative_amounts. */ unsigned int cumulative_amount_len; + }; /** * Statistic amount aggregated by interval. */ -struct TALER_MERCHANT_StatisticAmountByInterval +struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval { + /** * Start time of the interval (inclusive). * The interval always ends at the response @@ -79,7 +222,7 @@ struct TALER_MERCHANT_StatisticAmountByInterval struct TALER_Amount *cumulative_amounts; /** - * Length of array @a cumulative_amounts + * Length of array @a cumulative_amounts. */ unsigned int cumulative_amount_len; @@ -87,15 +230,9 @@ struct TALER_MERCHANT_StatisticAmountByInterval /** - * Handle for a GET .../statistics/amount/$SLUG request. + * Response details for a GET /private/statistics-amount/$SLUG request. */ -struct TALER_MERCHANT_StatisticsAmountGetHandle; - - -/** - * Response details for a GET .../statistics/amount/$SLUG request. - */ -struct TALER_MERCHANT_StatisticsAmountGetResponse +struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse { /** @@ -123,7 +260,7 @@ struct TALER_MERCHANT_StatisticsAmountGetResponse /** * Array of amount statistics per bucket. */ - const struct TALER_MERCHANT_StatisticAmountByBucket *buckets; + const struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket *buckets; /** * Description of the bucket aggregation scheme, or NULL. @@ -138,7 +275,8 @@ struct TALER_MERCHANT_StatisticsAmountGetResponse /** * Array of amount statistics per time interval. */ - const struct TALER_MERCHANT_StatisticAmountByInterval *intervals; + const struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval * + intervals; /** * Description of the interval aggregation scheme, or NULL. @@ -152,47 +290,53 @@ struct TALER_MERCHANT_StatisticsAmountGetResponse }; +#ifndef TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE /** - * Callback for a GET .../statistics/amount/$SLUG request. + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateStatisticsAmountCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE */ + +/** + * Callback for a GET /private/statistics-amount/$SLUG request. * * @param cls closure * @param sagr response details */ typedef void -(*TALER_MERCHANT_StatisticsAmountGetCallback)( - void *cls, - const struct TALER_MERCHANT_StatisticsAmountGetResponse *sagr); +(*TALER_MERCHANT_GetPrivateStatisticsAmountCallback)( + TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse *sagr); /** - * Issue a GET .../statistics/amount/$SLUG request. + * Start GET /private/statistics-amount/$SLUG operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param slug statistics slug to retrieve - * @param stype aggregation mode to request - * @param cb callback to invoke with the result + * @param[in,out] sah operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_StatisticsAmountGetHandle * -TALER_MERCHANT_statistic_amount_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *slug, - enum TALER_MERCHANT_StatisticsType stype, - TALER_MERCHANT_StatisticsAmountGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_statistics_amount_start ( + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, + TALER_MERCHANT_GetPrivateStatisticsAmountCallback cb, + TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET .../statistics/amount/$SLUG request. + * Cancel GET /private/statistics-amount/$SLUG operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateStatisticsAmountCallback has been invoked + * (as in those cases it'll be called internally by the implementation + * already). * - * @param[in] sagh handle to cancel + * @param[in] sah operation to cancel */ void -TALER_MERCHANT_statistic_amount_get_cancel ( - struct TALER_MERCHANT_StatisticsAmountGetHandle *sagh); +TALER_MERCHANT_get_private_statistics_amount_cancel ( + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_STATISTICS_AMOUNT_SLUG_H */ diff --git a/src/include/taler/taler-merchant/get-private-statistics-counter-SLUG-new.h b/src/include/taler/taler-merchant/get-private-statistics-counter-SLUG-new.h @@ -1,333 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-statistics-counter-SLUG-new.h - * @brief C interface for the GET /private/statistics-counter/$SLUG endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_STATISTICS_COUNTER_SLUG_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_STATISTICS_COUNTER_SLUG_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /private/statistics-counter/$SLUG request. - */ -enum TALER_MERCHANT_GetPrivateStatisticsCounterOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_END = 0, - - /** - * Aggregation mode to request (BUCKET, INTERVAL, or ANY). - */ - TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE - -}; - - -/** - * Value for an option for the GET /private/statistics-counter/$SLUG request. - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetPrivateStatisticsCounterOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE. - */ - enum TALER_MERCHANT_StatisticsType type; - - } details; - -}; - - -/** - * Handle for a GET /private/statistics-counter/$SLUG request. - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle; - - -/** - * Set up GET /private/statistics-counter/$SLUG operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param slug statistics slug to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle * -TALER_MERCHANT_get_private_statistics_counter_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *slug); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue - */ -#define TALER_MERCHANT_get_private_statistics_counter_option_end_() \ - (const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_END \ - } - -/** - * Set aggregation mode type. - * - * @param t aggregation mode to request - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue - */ -#define TALER_MERCHANT_get_private_statistics_counter_option_type(t) \ - (const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE, \ - .details.type = (t) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param sch 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_statistics_counter_set_options_ ( - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue *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_statistics_counter_set_options ( - * sch, - * TALER_MERCHANT_get_private_statistics_counter_option_type ( - * TALER_MERCHANT_STATISTICS_TYPE_INTERVAL)); - * - * @param sch the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_private_statistics_counter_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_private_statistics_counter_set_options(sch,...) \ - TALER_MERCHANT_get_private_statistics_counter_set_options_ ( \ - sch, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue[] \ - ) \ - {__VA_ARGS__, \ - TALER_MERCHANT_get_private_statistics_counter_option_end_ () } \ - )) - - -/** - * Statistic counter aggregated by bucket. - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket -{ - - /** - * Start time of the bucket (inclusive). - */ - struct GNUNET_TIME_Timestamp start_time; - - /** - * End time of the bucket (exclusive). - */ - struct GNUNET_TIME_Timestamp end_time; - - /** - * Range of the bucket. - */ - const char *range; - - /** - * Sum of all counters falling under the given - * SLUG within this timeframe. - */ - uint64_t cumulative_counter; - -}; - - -/** - * Statistic counter aggregated by interval. - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval -{ - - /** - * Start time of the interval (inclusive). - * The interval always ends at the response - * generation time. - */ - struct GNUNET_TIME_Timestamp start_time; - - /** - * Sum of all counters falling under the given - * SLUG within this timeframe. - */ - uint64_t cumulative_counter; - -}; - - -/** - * Response details for a GET /private/statistics-counter/$SLUG request. - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of bucket entries in @a buckets. - */ - unsigned int buckets_length; - - /** - * Array of counter statistics per bucket. - */ - const struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket *buckets; - - /** - * Description of the bucket aggregation scheme, or NULL. - */ - const char *buckets_description; - - /** - * Number of interval entries in @a intervals. - */ - unsigned int intervals_length; - - /** - * Array of counter statistics per time interval. - */ - const struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval * - intervals; - - /** - * Description of the interval aggregation scheme, or NULL. - */ - const char *intervals_description; - - } ok; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateStatisticsCounterCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/statistics-counter/$SLUG request. - * - * @param cls closure - * @param scgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateStatisticsCounterCallback)( - TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse *scgr); - - -/** - * Start GET /private/statistics-counter/$SLUG operation. - * - * @param[in,out] sch operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_statistics_counter_start ( - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, - TALER_MERCHANT_GetPrivateStatisticsCounterCallback cb, - TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/statistics-counter/$SLUG operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateStatisticsCounterCallback has been invoked - * (as in those cases it'll be called internally by the implementation - * already). - * - * @param[in] sch operation to cancel - */ -void -TALER_MERCHANT_get_private_statistics_counter_cancel ( - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_STATISTICS_COUNTER_SLUG_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-statistics-counter-SLUG.h b/src/include/taler/taler-merchant/get-private-statistics-counter-SLUG.h @@ -15,27 +15,163 @@ <http://www.gnu.org/licenses/> */ /** - * @file include/taler/taler-merchant/get-management-instances-INSTANCE-statistics-counter-SLUG.h - * @brief C interface for GET .../statistics/counter/$SLUG of the merchant backend + * @file include/taler/taler-merchant/get-private-statistics-counter-SLUG.h + * @brief C interface for the GET /private/statistics-counter/$SLUG endpoint * @author Christian Grothoff */ -#ifndef \ - _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_STATISTICS_COUNTER_SLUG_H -#define \ - _TALER_MERCHANT__GET_MANAGEMENT_INSTANCES_INSTANCE_STATISTICS_COUNTER_SLUG_H +#ifndef _TALER_MERCHANT__GET_PRIVATE_STATISTICS_COUNTER_SLUG_H +#define _TALER_MERCHANT__GET_PRIVATE_STATISTICS_COUNTER_SLUG_H #include <taler/taler-merchant/common.h> /** - * Handle for a GET .../statistics/counter/$SLUG request. + * Possible options we can set for the GET /private/statistics-counter/$SLUG request. */ -struct TALER_MERCHANT_StatisticsCounterGetHandle; +enum TALER_MERCHANT_GetPrivateStatisticsCounterOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_END = 0, + + /** + * Aggregation mode to request (BUCKET, INTERVAL, or ANY). + */ + TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE + +}; + + +/** + * Value for an option for the GET /private/statistics-counter/$SLUG request. + */ +struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateStatisticsCounterOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE. + */ + enum TALER_MERCHANT_StatisticsType type; + + } details; + +}; + + +/** + * Handle for a GET /private/statistics-counter/$SLUG request. + */ +struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle; + + +/** + * Set up GET /private/statistics-counter/$SLUG operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param slug statistics slug to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle * +TALER_MERCHANT_get_private_statistics_counter_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *slug); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue + */ +#define TALER_MERCHANT_get_private_statistics_counter_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_END \ + } + +/** + * Set aggregation mode type. + * + * @param t aggregation mode to request + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue + */ +#define TALER_MERCHANT_get_private_statistics_counter_option_type(t) \ + (const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE, \ + .details.type = (t) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param sch 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_statistics_counter_set_options_ ( + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue *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_statistics_counter_set_options ( + * sch, + * TALER_MERCHANT_get_private_statistics_counter_option_type ( + * TALER_MERCHANT_STATISTICS_TYPE_INTERVAL)); + * + * @param sch the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_statistics_counter_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_statistics_counter_set_options(sch,...) \ + TALER_MERCHANT_get_private_statistics_counter_set_options_ ( \ + sch, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue[] \ + ) \ + {__VA_ARGS__, \ + TALER_MERCHANT_get_private_statistics_counter_option_end_ () } \ + )) + /** * Statistic counter aggregated by bucket. */ -struct TALER_MERCHANT_StatisticCounterByBucket +struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket { /** @@ -49,7 +185,7 @@ struct TALER_MERCHANT_StatisticCounterByBucket struct GNUNET_TIME_Timestamp end_time; /** - * Range of the bucket + * Range of the bucket. */ const char *range; @@ -65,7 +201,7 @@ struct TALER_MERCHANT_StatisticCounterByBucket /** * Statistic counter aggregated by interval. */ -struct TALER_MERCHANT_StatisticCounterByInterval +struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval { /** @@ -85,9 +221,9 @@ struct TALER_MERCHANT_StatisticCounterByInterval /** - * Response details for a GET .../statistics/counter/$SLUG request. + * Response details for a GET /private/statistics-counter/$SLUG request. */ -struct TALER_MERCHANT_StatisticsCounterGetResponse +struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse { /** @@ -115,7 +251,7 @@ struct TALER_MERCHANT_StatisticsCounterGetResponse /** * Array of counter statistics per bucket. */ - const struct TALER_MERCHANT_StatisticCounterByBucket *buckets; + const struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket *buckets; /** * Description of the bucket aggregation scheme, or NULL. @@ -130,7 +266,8 @@ struct TALER_MERCHANT_StatisticsCounterGetResponse /** * Array of counter statistics per time interval. */ - const struct TALER_MERCHANT_StatisticCounterByInterval *intervals; + const struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval * + intervals; /** * Description of the interval aggregation scheme, or NULL. @@ -144,47 +281,53 @@ struct TALER_MERCHANT_StatisticsCounterGetResponse }; +#ifndef TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateStatisticsCounterCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE */ + /** - * Callback for a GET .../statistics/counter/$SLUG request. + * Callback for a GET /private/statistics-counter/$SLUG request. * * @param cls closure * @param scgr response details */ typedef void -(*TALER_MERCHANT_StatisticsCounterGetCallback)( - void *cls, - const struct TALER_MERCHANT_StatisticsCounterGetResponse *scgr); +(*TALER_MERCHANT_GetPrivateStatisticsCounterCallback)( + TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse *scgr); /** - * Issue a GET .../statistics/counter/$SLUG request. + * Start GET /private/statistics-counter/$SLUG operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param slug statistics slug to retrieve - * @param stype aggregation mode to request - * @param cb callback to invoke with the result + * @param[in,out] sch operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_StatisticsCounterGetHandle * -TALER_MERCHANT_statistic_counter_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *slug, - enum TALER_MERCHANT_StatisticsType stype, - TALER_MERCHANT_StatisticsCounterGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_statistics_counter_start ( + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, + TALER_MERCHANT_GetPrivateStatisticsCounterCallback cb, + TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET .../statistics/counter/$SLUG request. + * Cancel GET /private/statistics-counter/$SLUG operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateStatisticsCounterCallback has been invoked + * (as in those cases it'll be called internally by the implementation + * already). * - * @param[in] scgh handle to cancel + * @param[in] sch operation to cancel */ void -TALER_MERCHANT_statistic_counter_get_cancel ( - struct TALER_MERCHANT_StatisticsCounterGetHandle *scgh); +TALER_MERCHANT_get_private_statistics_counter_cancel ( + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_STATISTICS_COUNTER_SLUG_H */ diff --git a/src/include/taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h b/src/include/taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h @@ -1,145 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h - * @brief C interface for GET /private/templates/$TEMPLATE_ID of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_GetPrivateTemplateHandle; - - -/** - * Response details for a GET /private/templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_GetPrivateTemplateResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Human-readable description of the template. - */ - const char *template_description; - - /** - * OTP device ID associated with this template, or NULL. - */ - const char *otp_id; - - /** - * Template contract (JSON). - */ - const json_t *template_contract; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/templates/$TEMPLATE_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param template_id identifier of the template to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateTemplateHandle * -TALER_MERCHANT_get_private_template_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateTemplateCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/templates/$TEMPLATE_ID request. - * - * @param cls closure - * @param tgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateTemplateCallback)( - TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateTemplateResponse *tgr); - - -/** - * Start GET /private/templates/$TEMPLATE_ID operation. - * - * @param[in,out] gpt operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_template_start ( - struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt, - TALER_MERCHANT_GetPrivateTemplateCallback cb, - TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/templates/$TEMPLATE_ID operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateTemplateCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpt operation to cancel - */ -void -TALER_MERCHANT_get_private_template_cancel ( - struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-templates-TEMPLATE_ID.h b/src/include/taler/taler-merchant/get-private-templates-TEMPLATE_ID.h @@ -28,13 +28,13 @@ /** * Handle for a GET /private/templates/$TEMPLATE_ID request. */ -struct TALER_MERCHANT_TemplateGetHandle; +struct TALER_MERCHANT_GetPrivateTemplateHandle; /** * Response details for a GET /private/templates/$TEMPLATE_ID request. */ -struct TALER_MERCHANT_TemplateGetResponse +struct TALER_MERCHANT_GetPrivateTemplateResponse { /** @@ -77,43 +77,69 @@ struct TALER_MERCHANT_TemplateGetResponse /** + * Set up GET /private/templates/$TEMPLATE_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param template_id identifier of the template to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateTemplateHandle * +TALER_MERCHANT_get_private_template_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *template_id); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateTemplateCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE */ + +/** * Callback for a GET /private/templates/$TEMPLATE_ID request. * * @param cls closure * @param tgr response details */ typedef void -(*TALER_MERCHANT_TemplateGetCallback)( - void *cls, - const struct TALER_MERCHANT_TemplateGetResponse *tgr); +(*TALER_MERCHANT_GetPrivateTemplateCallback)( + TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateTemplateResponse *tgr); /** - * Issue a GET /private/templates/$TEMPLATE_ID request. + * Start GET /private/templates/$TEMPLATE_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param template_id identifier of the template to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gpt operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_TemplateGetHandle * -TALER_MERCHANT_template_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - TALER_MERCHANT_TemplateGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_template_start ( + struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt, + TALER_MERCHANT_GetPrivateTemplateCallback cb, + TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/templates/$TEMPLATE_ID request. + * Cancel GET /private/templates/$TEMPLATE_ID operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateTemplateCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] gpt operation to cancel */ void -TALER_MERCHANT_template_get_cancel ( - struct TALER_MERCHANT_TemplateGetHandle *tgh); +TALER_MERCHANT_get_private_template_cancel ( + struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_TEMPLATE_ID_H */ diff --git a/src/include/taler/taler-merchant/get-private-templates-new.h b/src/include/taler/taler-merchant/get-private-templates-new.h @@ -1,156 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-templates-new.h - * @brief C interface for the GET /private/templates endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/templates request. - */ -struct TALER_MERCHANT_GetPrivateTemplatesHandle; - - -/** - * Entry for one order template. - */ -struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry -{ - - /** - * Identifier of the template. - */ - const char *template_id; - - /** - * Human-readable description of the template. - */ - const char *template_description; - -}; - - -/** - * Response details for a GET /private/templates request. - */ -struct TALER_MERCHANT_GetPrivateTemplatesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of templates in @a templates. - */ - unsigned int templates_length; - - /** - * Array of template entries. - */ - const struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry *templates; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/templates operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateTemplatesHandle * -TALER_MERCHANT_get_private_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateTemplatesCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/templates request. - * - * @param cls closure - * @param tgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateTemplatesCallback)( - TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateTemplatesResponse *tgr); - - -/** - * Start GET /private/templates operation. - * - * @param[in,out] gpth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_templates_start ( - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth, - TALER_MERCHANT_GetPrivateTemplatesCallback cb, - TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/templates operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateTemplatesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpth operation to cancel - */ -void -TALER_MERCHANT_get_private_templates_cancel ( - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-templates.h b/src/include/taler/taler-merchant/get-private-templates.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-templates.h - * @brief C interface for GET /private/templates of the merchant backend + * @brief C interface for the GET /private/templates endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_H @@ -28,13 +28,13 @@ /** * Handle for a GET /private/templates request. */ -struct TALER_MERCHANT_TemplatesGetHandle; +struct TALER_MERCHANT_GetPrivateTemplatesHandle; /** * Entry for one order template. */ -struct TALER_MERCHANT_TemplateEntry +struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry { /** @@ -53,7 +53,7 @@ struct TALER_MERCHANT_TemplateEntry /** * Response details for a GET /private/templates request. */ -struct TALER_MERCHANT_TemplatesGetResponse +struct TALER_MERCHANT_GetPrivateTemplatesResponse { /** @@ -81,7 +81,7 @@ struct TALER_MERCHANT_TemplatesGetResponse /** * Array of template entries. */ - const struct TALER_MERCHANT_TemplateEntry *templates; + const struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry *templates; } ok; @@ -91,41 +91,66 @@ struct TALER_MERCHANT_TemplatesGetResponse /** + * Set up GET /private/templates operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateTemplatesHandle * +TALER_MERCHANT_get_private_templates_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateTemplatesCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE */ + +/** * Callback for a GET /private/templates request. * * @param cls closure * @param tgr response details */ typedef void -(*TALER_MERCHANT_TemplatesGetCallback)( - void *cls, - const struct TALER_MERCHANT_TemplatesGetResponse *tgr); +(*TALER_MERCHANT_GetPrivateTemplatesCallback)( + TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateTemplatesResponse *tgr); /** - * Issue a GET /private/templates request. + * Start GET /private/templates operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpth operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_TemplatesGetHandle * -TALER_MERCHANT_templates_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_TemplatesGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_templates_start ( + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth, + TALER_MERCHANT_GetPrivateTemplatesCallback cb, + TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/templates request. + * Cancel GET /private/templates operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateTemplatesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] gpth operation to cancel */ void -TALER_MERCHANT_templates_get_cancel ( - struct TALER_MERCHANT_TemplatesGetHandle *tgh); +TALER_MERCHANT_get_private_templates_cancel ( + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_TEMPLATES_H */ diff --git a/src/include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.h b/src/include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.h @@ -1,196 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.h - * @brief C interface for GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG - * of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_TOKENFAMILIES_TOKEN_FAMILY_SLUG_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_TOKENFAMILIES_TOKEN_FAMILY_SLUG_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. - */ -struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle; - - -/** - * Response details for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. - */ -struct TALER_MERCHANT_GetPrivateTokenfamiliesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * URL-safe slug identifier of the token family. - */ - const char *slug; - - /** - * Human-readable name. - */ - const char *name; - - /** - * Human-readable description. - */ - const char *description; - - /** - * Internationalized descriptions (JSON), or NULL. - */ - const json_t *description_i18n; - - /** - * Extra data associated with this token family (JSON), or NULL. - */ - const json_t *extra_data; - - /** - * Start of validity period. - */ - struct GNUNET_TIME_Timestamp valid_after; - - /** - * End of validity period. - */ - struct GNUNET_TIME_Timestamp valid_before; - - /** - * Duration of individual token validity. - */ - struct GNUNET_TIME_Relative duration; - - /** - * Granularity for validity period alignment. - */ - struct GNUNET_TIME_Relative validity_granularity; - - /** - * Offset from purchase time to start of validity. - */ - struct GNUNET_TIME_Relative start_offset; - - /** - * Kind of token family ("subscription" or "discount"). - */ - const char *kind; - - /** - * Total number of tokens issued. - */ - uint64_t issued; - - /** - * Total number of tokens used. - */ - uint64_t used; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param token_family_slug slug of the token family to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle * -TALER_MERCHANT_get_private_tokenfamilies_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *token_family_slug); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateTokenfamiliesCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. - * - * @param cls closure - * @param tfgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateTokenfamiliesCallback)( - TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateTokenfamiliesResponse *tfgr); - - -/** - * Start GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. - * - * @param[in,out] gptf operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_tokenfamilies_start ( - struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf, - TALER_MERCHANT_GetPrivateTokenfamiliesCallback cb, - TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. - * This function must not be called by clients after the - * TALER_MERCHANT_GetPrivateTokenfamiliesCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gptf operation to cancel - */ -void -TALER_MERCHANT_get_private_tokenfamilies_cancel ( - struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_TOKENFAMILIES_TOKEN_FAMILY_SLUG_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG.h b/src/include/taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG.h @@ -29,13 +29,13 @@ /** * Handle for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. */ -struct TALER_MERCHANT_TokenFamilyGetHandle; +struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle; /** * Response details for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. */ -struct TALER_MERCHANT_TokenFamilyGetResponse +struct TALER_MERCHANT_GetPrivateTokenfamiliesResponse { /** @@ -128,44 +128,69 @@ struct TALER_MERCHANT_TokenFamilyGetResponse /** + * Set up GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param token_family_slug slug of the token family to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle * +TALER_MERCHANT_get_private_tokenfamilies_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *token_family_slug); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateTokenfamiliesCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE */ + +/** * Callback for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. * * @param cls closure * @param tfgr response details */ typedef void -(*TALER_MERCHANT_TokenFamilyGetCallback)( - void *cls, - const struct TALER_MERCHANT_TokenFamilyGetResponse *tfgr); +(*TALER_MERCHANT_GetPrivateTokenfamiliesCallback)( + TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateTokenfamiliesResponse *tfgr); /** - * Issue a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. + * Start GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param token_family_slug slug of the token family to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gptf operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_TokenFamilyGetHandle * -TALER_MERCHANT_token_family_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *token_family_slug, - TALER_MERCHANT_TokenFamilyGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_tokenfamilies_start ( + struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf, + TALER_MERCHANT_GetPrivateTokenfamiliesCallback cb, + TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. + * Cancel GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. + * This function must not be called by clients after the + * TALER_MERCHANT_GetPrivateTokenfamiliesCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] handle handle to cancel + * @param[in] gptf operation to cancel */ void -TALER_MERCHANT_token_family_get_cancel ( - struct TALER_MERCHANT_TokenFamilyGetHandle *handle); +TALER_MERCHANT_get_private_tokenfamilies_cancel ( + struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_TOKENFAMILIES_TOKEN_FAMILY_SLUG_H */ diff --git a/src/include/taler/taler-merchant/get-private-transfers-new.h b/src/include/taler/taler-merchant/get-private-transfers-new.h @@ -1,423 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-transfers-new.h - * @brief C interface for the GET /private/transfers endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_TRANSFERS_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_TRANSFERS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the GET /private/transfers request. - */ -enum TALER_MERCHANT_GetPrivateTransfersOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_END = 0, - - /** - * Filter by payto URI. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI, - - /** - * Filter for transfers before this time. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE, - - /** - * Filter for transfers after this time. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER, - - /** - * Return at most N values. Negative values - * to return in descending order, positive for ascending. - * Default is -20. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT, - - /** - * Starting transfer_serial_id for pagination. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET, - - /** - * Filter by verification/expected status. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED - -}; - - -/** - * Value for an option for the GET /private/transfers request. - */ -struct TALER_MERCHANT_GetPrivateTransfersOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_GetPrivateTransfersOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI. - */ - struct TALER_FullPayto payto_uri; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE. - */ - struct GNUNET_TIME_Timestamp before; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER. - */ - struct GNUNET_TIME_Timestamp after; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT. - */ - int64_t limit; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET. - */ - uint64_t offset; - - /** - * Value if @e option is - * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED. - */ - enum TALER_EXCHANGE_YesNoAll expected; - - } details; - -}; - - -/** - * Handle for a GET /private/transfers request. - */ -struct TALER_MERCHANT_GetPrivateTransfersHandle; - - -/** - * Set up GET /private/transfers operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateTransfersHandle * -TALER_MERCHANT_get_private_transfers_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_end_() \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_END \ - } - -/** - * Set payto URI filter. - * - * @param p payto URI to filter by - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_payto_uri(p) \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI, \ - .details.payto_uri = (p) \ - } - -/** - * Set filter for transfers before the given timestamp. - * - * @param t timestamp threshold - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_before(t) \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE, \ - .details.before = (t) \ - } - -/** - * Set filter for transfers after the given timestamp. - * - * @param t timestamp threshold - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_after(t) \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER, \ - .details.after = (t) \ - } - -/** - * Set limit on the number of results to return. - * - * @param l limit on the number of results to return - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_limit(l) \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT, \ - .details.limit = (l) \ - } - -/** - * Set row offset from which to return results. - * - * @param o offset to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_offset(o) \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET, \ - .details.offset = (o) \ - } - -/** - * Set filter on expected/verified status. - * - * @param e expected filter to use - * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue - */ -#define TALER_MERCHANT_get_private_transfers_option_expected(e) \ - (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ - { \ - .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED, \ - .details.expected = (e) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param gth 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_transfers_set_options_ ( - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateTransfersOptionValue *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_transfers_set_options ( - * gth, - * TALER_MERCHANT_get_private_transfers_option_limit (-20), - * TALER_MERCHANT_get_private_transfers_option_expected ( - * TALER_EXCHANGE_YNA_YES)); - * - * @param gth the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_get_private_transfers_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_get_private_transfers_set_options(gth,...) \ - TALER_MERCHANT_get_private_transfers_set_options_ ( \ - gth, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_GetPrivateTransfersOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_get_private_transfers_option_end_ () } \ - )) - - -/** - * Transfer data entry. - */ -struct TALER_MERCHANT_GetPrivateTransfersTransferData -{ - - /** - * Total amount wired by the exchange (without wire fee). - */ - struct TALER_Amount credit_amount; - - /** - * Wire transfer identifier used. - */ - struct TALER_WireTransferIdentifierRawP wtid; - - /** - * URI of the target account. - */ - struct TALER_FullPayto payto_uri; - - /** - * URL of the exchange that made the transfer. - */ - const char *exchange_url; - - /** - * Serial number of the credit operation in the merchant backend. - */ - uint64_t credit_serial; - - /** - * Time of the wire transfer, based on when we received - * a confirmation for the wire transfer. - */ - struct GNUNET_TIME_Timestamp execution_time; - - /** - * True if this wire transfer was expected. - */ - bool expected; - -}; - - -/** - * Response details for a GET /private/transfers request. - */ -struct TALER_MERCHANT_GetPrivateTransfersResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of transfers in @a transfers. - */ - unsigned int transfers_length; - - /** - * Array of transfer data entries. - */ - const struct TALER_MERCHANT_GetPrivateTransfersTransferData *transfers; - - } ok; - - } details; - -}; - - -#ifndef TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateTransfersCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/transfers request. - * - * @param cls closure - * @param gtr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateTransfersCallback)( - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateTransfersResponse *gtr); - - -/** - * Start GET /private/transfers operation. - * - * @param[in,out] gth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_transfers_start ( - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, - TALER_MERCHANT_GetPrivateTransfersCallback cb, - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/transfers operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateTransfersCallback - * has been invoked (as in those cases it'll be called internally by - * the implementation already). - * - * @param[in] gth operation to cancel - */ -void -TALER_MERCHANT_get_private_transfers_cancel ( - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_TRANSFERS_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-transfers.h b/src/include/taler/taler-merchant/get-private-transfers.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-transfers.h - * @brief C interface for GET /private/transfers of the merchant backend + * @brief C interface for the GET /private/transfers endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_TRANSFERS_H @@ -26,20 +26,275 @@ /** + * Possible options we can set for the GET /private/transfers request. + */ +enum TALER_MERCHANT_GetPrivateTransfersOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_END = 0, + + /** + * Filter by payto URI. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI, + + /** + * Filter for transfers before this time. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE, + + /** + * Filter for transfers after this time. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER, + + /** + * Return at most N values. Negative values + * to return in descending order, positive for ascending. + * Default is -20. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT, + + /** + * Starting transfer_serial_id for pagination. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET, + + /** + * Filter by verification/expected status. + */ + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED + +}; + + +/** + * Value for an option for the GET /private/transfers request. + */ +struct TALER_MERCHANT_GetPrivateTransfersOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_GetPrivateTransfersOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI. + */ + struct TALER_FullPayto payto_uri; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE. + */ + struct GNUNET_TIME_Timestamp before; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER. + */ + struct GNUNET_TIME_Timestamp after; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT. + */ + int64_t limit; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET. + */ + uint64_t offset; + + /** + * Value if @e option is + * #TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED. + */ + enum TALER_EXCHANGE_YesNoAll expected; + + } details; + +}; + + +/** * Handle for a GET /private/transfers request. */ -struct TALER_MERCHANT_GetTransfersHandle; +struct TALER_MERCHANT_GetPrivateTransfersHandle; + + +/** + * Set up GET /private/transfers operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateTransfersHandle * +TALER_MERCHANT_get_private_transfers_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_end_() \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_END \ + } + +/** + * Set payto URI filter. + * + * @param p payto URI to filter by + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_payto_uri(p) \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI, \ + .details.payto_uri = (p) \ + } + +/** + * Set filter for transfers before the given timestamp. + * + * @param t timestamp threshold + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_before(t) \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE, \ + .details.before = (t) \ + } + +/** + * Set filter for transfers after the given timestamp. + * + * @param t timestamp threshold + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_after(t) \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER, \ + .details.after = (t) \ + } + +/** + * Set limit on the number of results to return. + * + * @param l limit on the number of results to return + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_limit(l) \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT, \ + .details.limit = (l) \ + } + +/** + * Set row offset from which to return results. + * + * @param o offset to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_offset(o) \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET, \ + .details.offset = (o) \ + } + +/** + * Set filter on expected/verified status. + * + * @param e expected filter to use + * @return representation of the option as a struct TALER_MERCHANT_GetPrivateTransfersOptionValue + */ +#define TALER_MERCHANT_get_private_transfers_option_expected(e) \ + (const struct TALER_MERCHANT_GetPrivateTransfersOptionValue) \ + { \ + .option = TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED, \ + .details.expected = (e) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param gth 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_transfers_set_options_ ( + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateTransfersOptionValue *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_transfers_set_options ( + * gth, + * TALER_MERCHANT_get_private_transfers_option_limit (-20), + * TALER_MERCHANT_get_private_transfers_option_expected ( + * TALER_EXCHANGE_YNA_YES)); + * + * @param gth the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_get_private_transfers_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_get_private_transfers_set_options(gth,...) \ + TALER_MERCHANT_get_private_transfers_set_options_ ( \ + gth, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_GetPrivateTransfersOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_get_private_transfers_option_end_ () } \ + )) /** * Transfer data entry. */ -struct TALER_MERCHANT_TransferData +struct TALER_MERCHANT_GetPrivateTransfersTransferData { - /** - * Total amount wired by the exchange (without wire fee) + * Total amount wired by the exchange (without wire fee). */ struct TALER_Amount credit_amount; @@ -60,8 +315,6 @@ struct TALER_MERCHANT_TransferData /** * Serial number of the credit operation in the merchant backend. - * Needed, for example, to delete the transfer using - * #TALER_MERCHANT_transfer_delete(). */ uint64_t credit_serial; @@ -82,7 +335,7 @@ struct TALER_MERCHANT_TransferData /** * Response details for a GET /private/transfers request. */ -struct TALER_MERCHANT_GetTransfersResponse +struct TALER_MERCHANT_GetPrivateTransfersResponse { /** @@ -110,7 +363,7 @@ struct TALER_MERCHANT_GetTransfersResponse /** * Array of transfer data entries. */ - const struct TALER_MERCHANT_TransferData *transfers; + const struct TALER_MERCHANT_GetPrivateTransfersTransferData *transfers; } ok; @@ -119,6 +372,14 @@ struct TALER_MERCHANT_GetTransfersResponse }; +#ifndef TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateTransfersCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE */ + /** * Callback for a GET /private/transfers request. * @@ -126,48 +387,37 @@ struct TALER_MERCHANT_GetTransfersResponse * @param gtr response details */ typedef void -(*TALER_MERCHANT_GetTransfersCallback)( - void *cls, - const struct TALER_MERCHANT_GetTransfersResponse *gtr); +(*TALER_MERCHANT_GetPrivateTransfersCallback)( + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateTransfersResponse *gtr); /** - * Issue a GET /private/transfers request. + * Start GET /private/transfers operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param payto_uri filter by payto URI (may be empty) - * @param before filter for transfers before this time - * @param after filter for transfers after this time - * @param limit maximum number of results (negative for descending order) - * @param offset pagination offset - * @param expected filter by verification status - * @param cb callback to invoke with the result + * @param[in,out] gth operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_GetTransfersHandle * -TALER_MERCHANT_transfers_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - struct TALER_FullPayto payto_uri, - const struct GNUNET_TIME_Timestamp before, - const struct GNUNET_TIME_Timestamp after, - int64_t limit, - uint64_t offset, - enum TALER_EXCHANGE_YesNoAll expected, - TALER_MERCHANT_GetTransfersCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_transfers_start ( + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, + TALER_MERCHANT_GetPrivateTransfersCallback cb, + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/transfers request. + * Cancel GET /private/transfers operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateTransfersCallback + * has been invoked (as in those cases it'll be called internally by + * the implementation already). * - * @param[in] gth handle to cancel + * @param[in] gth operation to cancel */ void -TALER_MERCHANT_transfers_get_cancel ( - struct TALER_MERCHANT_GetTransfersHandle *gth); +TALER_MERCHANT_get_private_transfers_cancel ( + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_TRANSFERS_H */ diff --git a/src/include/taler/taler-merchant/get-private-units-UNIT-new.h b/src/include/taler/taler-merchant/get-private-units-UNIT-new.h @@ -1,135 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-units-UNIT-new.h - * @brief C interface for GET /private/units/$UNIT of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_UNITS_UNIT_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_UNITS_UNIT_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/units/$UNIT request. - */ -struct TALER_MERCHANT_GetPrivateUnitHandle; - - -/** - * Response details for a GET /private/units/$UNIT request. - */ -struct TALER_MERCHANT_GetPrivateUnitResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Detailed unit information. - */ - struct TALER_MERCHANT_UnitEntry unit; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/units/$UNIT operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param unit_id identifier of the unit to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateUnitHandle * -TALER_MERCHANT_get_private_unit_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *unit_id); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateUnitCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/units/$UNIT request. - * - * @param cls closure - * @param ugr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateUnitCallback)( - TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateUnitResponse *ugr); - - -/** - * Start GET /private/units/$UNIT operation. - * - * @param[in,out] gpu operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_unit_start ( - struct TALER_MERCHANT_GetPrivateUnitHandle *gpu, - TALER_MERCHANT_GetPrivateUnitCallback cb, - TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/units/$UNIT operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateUnitCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpu operation to cancel - */ -void -TALER_MERCHANT_get_private_unit_cancel ( - struct TALER_MERCHANT_GetPrivateUnitHandle *gpu); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_UNITS_UNIT_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-units-UNIT.h b/src/include/taler/taler-merchant/get-private-units-UNIT.h @@ -28,13 +28,13 @@ /** * Handle for a GET /private/units/$UNIT request. */ -struct TALER_MERCHANT_UnitGetHandle; +struct TALER_MERCHANT_GetPrivateUnitHandle; /** * Response details for a GET /private/units/$UNIT request. */ -struct TALER_MERCHANT_UnitGetResponse +struct TALER_MERCHANT_GetPrivateUnitResponse { /** @@ -67,43 +67,69 @@ struct TALER_MERCHANT_UnitGetResponse /** + * Set up GET /private/units/$UNIT operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param unit_id identifier of the unit to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateUnitHandle * +TALER_MERCHANT_get_private_unit_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *unit_id); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateUnitCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE */ + +/** * Callback for a GET /private/units/$UNIT request. * * @param cls closure * @param ugr response details */ typedef void -(*TALER_MERCHANT_UnitGetCallback)( - void *cls, - const struct TALER_MERCHANT_UnitGetResponse *ugr); +(*TALER_MERCHANT_GetPrivateUnitCallback)( + TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateUnitResponse *ugr); /** - * Issue a GET /private/units/$UNIT request. + * Start GET /private/units/$UNIT operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param unit_id identifier of the unit to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gpu operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_UnitGetHandle * -TALER_MERCHANT_unit_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *unit_id, - TALER_MERCHANT_UnitGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_unit_start ( + struct TALER_MERCHANT_GetPrivateUnitHandle *gpu, + TALER_MERCHANT_GetPrivateUnitCallback cb, + TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/units/$UNIT request. + * Cancel GET /private/units/$UNIT operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateUnitCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] ugh handle to cancel + * @param[in] gpu operation to cancel */ void -TALER_MERCHANT_unit_get_cancel ( - struct TALER_MERCHANT_UnitGetHandle *ugh); +TALER_MERCHANT_get_private_unit_cancel ( + struct TALER_MERCHANT_GetPrivateUnitHandle *gpu); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_UNITS_UNIT_H */ diff --git a/src/include/taler/taler-merchant/get-private-units-new.h b/src/include/taler/taler-merchant/get-private-units-new.h @@ -1,137 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-units-new.h - * @brief C interface for the GET /private/units endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_UNITS_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_UNITS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/units request. - */ -struct TALER_MERCHANT_GetPrivateUnitsHandle; - - -/** - * Response details for a GET /private/units request. - */ -struct TALER_MERCHANT_GetPrivateUnitsResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of units in @a units. - */ - unsigned int units_length; - - /** - * Array of unit entries. - */ - const struct TALER_MERCHANT_UnitEntry *units; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/units operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateUnitsHandle * -TALER_MERCHANT_get_private_units_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateUnitsCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/units request. - * - * @param cls closure - * @param ugr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateUnitsCallback)( - TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateUnitsResponse *ugr); - - -/** - * Start GET /private/units operation. - * - * @param[in,out] gpuh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_units_start ( - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh, - TALER_MERCHANT_GetPrivateUnitsCallback cb, - TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/units operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateUnitsCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpuh operation to cancel - */ -void -TALER_MERCHANT_get_private_units_cancel ( - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_UNITS_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-units.h b/src/include/taler/taler-merchant/get-private-units.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-units.h - * @brief C interface for GET /private/units of the merchant backend + * @brief C interface for the GET /private/units endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_UNITS_H @@ -28,13 +28,13 @@ /** * Handle for a GET /private/units request. */ -struct TALER_MERCHANT_UnitsGetHandle; +struct TALER_MERCHANT_GetPrivateUnitsHandle; /** * Response details for a GET /private/units request. */ -struct TALER_MERCHANT_UnitsGetResponse +struct TALER_MERCHANT_GetPrivateUnitsResponse { /** @@ -72,41 +72,66 @@ struct TALER_MERCHANT_UnitsGetResponse /** + * Set up GET /private/units operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateUnitsHandle * +TALER_MERCHANT_get_private_units_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateUnitsCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE */ + +/** * Callback for a GET /private/units request. * * @param cls closure * @param ugr response details */ typedef void -(*TALER_MERCHANT_UnitsGetCallback)( - void *cls, - const struct TALER_MERCHANT_UnitsGetResponse *ugr); +(*TALER_MERCHANT_GetPrivateUnitsCallback)( + TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateUnitsResponse *ugr); /** - * Issue a GET /private/units request. + * Start GET /private/units operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpuh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_UnitsGetHandle * -TALER_MERCHANT_units_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_UnitsGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_units_start ( + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh, + TALER_MERCHANT_GetPrivateUnitsCallback cb, + TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/units request. + * Cancel GET /private/units operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateUnitsCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] ugh handle to cancel + * @param[in] gpuh operation to cancel */ void -TALER_MERCHANT_units_get_cancel ( - struct TALER_MERCHANT_UnitsGetHandle *ugh); +TALER_MERCHANT_get_private_units_cancel ( + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_UNITS_H */ diff --git a/src/include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h b/src/include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h @@ -1,156 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h - * @brief C interface for GET /private/webhooks/$WEBHOOK_ID of the merchant backend - * @author Priscilla Huang - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/webhooks/$WEBHOOK_ID request. - */ -struct TALER_MERCHANT_GetPrivateWebhookHandle; - - -/** - * Response details for a GET /private/webhooks/$WEBHOOK_ID request. - */ -struct TALER_MERCHANT_GetPrivateWebhookResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Event type that triggers this webhook. - */ - const char *event_type; - - /** - * URL to send the webhook notification to. - */ - const char *url; - - /** - * HTTP method to use. - */ - const char *http_method; - - /** - * Template for HTTP headers, or NULL. - */ - const char *header_template; - - /** - * Template for the HTTP body, or NULL. - */ - const char *body_template; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/webhooks/$WEBHOOK_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param webhook_id identifier of the webhook to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateWebhookHandle * -TALER_MERCHANT_get_private_webhook_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateWebhookCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/webhooks/$WEBHOOK_ID request. - * - * @param cls closure - * @param wgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateWebhookCallback)( - TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateWebhookResponse *wgr); - - -/** - * Start GET /private/webhooks/$WEBHOOK_ID operation. - * - * @param[in,out] gpw operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_webhook_start ( - struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw, - TALER_MERCHANT_GetPrivateWebhookCallback cb, - TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/webhooks/$WEBHOOK_ID operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetPrivateWebhookCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpw operation to cancel - */ -void -TALER_MERCHANT_get_private_webhook_cancel ( - struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID.h b/src/include/taler/taler-merchant/get-private-webhooks-WEBHOOK_ID.h @@ -29,57 +29,128 @@ /** * Handle for a GET /private/webhooks/$WEBHOOK_ID request. */ -struct TALER_MERCHANT_WebhookGetHandle; +struct TALER_MERCHANT_GetPrivateWebhookHandle; /** + * Response details for a GET /private/webhooks/$WEBHOOK_ID request. + */ +struct TALER_MERCHANT_GetPrivateWebhookResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + + /** + * Details depending on the HTTP status code. + */ + union + { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + + /** + * Event type that triggers this webhook. + */ + const char *event_type; + + /** + * URL to send the webhook notification to. + */ + const char *url; + + /** + * HTTP method to use. + */ + const char *http_method; + + /** + * Template for HTTP headers, or NULL. + */ + const char *header_template; + + /** + * Template for the HTTP body, or NULL. + */ + const char *body_template; + + } ok; + + } details; + +}; + + +/** + * Set up GET /private/webhooks/$WEBHOOK_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param webhook_id identifier of the webhook to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateWebhookHandle * +TALER_MERCHANT_get_private_webhook_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *webhook_id); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateWebhookCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE */ + +/** * Callback for a GET /private/webhooks/$WEBHOOK_ID request. * * @param cls closure - * @param hr HTTP response details - * @param event_type event type that triggers this webhook, or NULL on error - * @param url URL to send the webhook notification to, or NULL on error - * @param http_method HTTP method to use, or NULL on error - * @param header_template template for HTTP headers, or NULL on error - * @param body_template template for the HTTP body, or NULL on error + * @param wgr response details */ typedef void -(*TALER_MERCHANT_WebhookGetCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const char *event_type, - const char *url, - const char *http_method, - const char *header_template, - const char *body_template); +(*TALER_MERCHANT_GetPrivateWebhookCallback)( + TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateWebhookResponse *wgr); /** - * Issue a GET /private/webhooks/$WEBHOOK_ID request. + * Start GET /private/webhooks/$WEBHOOK_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param webhook_id identifier of the webhook to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gpw operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_WebhookGetHandle * -TALER_MERCHANT_webhook_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *webhook_id, - TALER_MERCHANT_WebhookGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_webhook_start ( + struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw, + TALER_MERCHANT_GetPrivateWebhookCallback cb, + TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/webhooks/$WEBHOOK_ID request. + * Cancel GET /private/webhooks/$WEBHOOK_ID operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetPrivateWebhookCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] wgh handle to cancel + * @param[in] gpw operation to cancel */ void -TALER_MERCHANT_webhook_get_cancel ( - struct TALER_MERCHANT_WebhookGetHandle *wgh); +TALER_MERCHANT_get_private_webhook_cancel ( + struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_WEBHOOK_ID_H */ diff --git a/src/include/taler/taler-merchant/get-private-webhooks-new.h b/src/include/taler/taler-merchant/get-private-webhooks-new.h @@ -1,156 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-private-webhooks-new.h - * @brief C interface for the GET /private/webhooks endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_NEW_H -#define _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /private/webhooks request. - */ -struct TALER_MERCHANT_GetPrivateWebhooksHandle; - - -/** - * Entry for one webhook. - */ -struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry -{ - - /** - * Identifier of the webhook. - */ - const char *webhook_id; - - /** - * Event type that triggers this webhook. - */ - const char *event_type; - -}; - - -/** - * Response details for a GET /private/webhooks request. - */ -struct TALER_MERCHANT_GetPrivateWebhooksResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of webhooks in @a webhooks. - */ - unsigned int webhooks_length; - - /** - * Array of webhook entries. - */ - const struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry *webhooks; - - } ok; - - } details; - -}; - - -/** - * Set up GET /private/webhooks operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @return handle to operation - */ -struct TALER_MERCHANT_GetPrivateWebhooksHandle * -TALER_MERCHANT_get_private_webhooks_create ( - struct GNUNET_CURL_Context *ctx, - const char *url); - - -#ifndef TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetPrivateWebhooksCallback. - */ -#define TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE */ - -/** - * Callback for a GET /private/webhooks request. - * - * @param cls closure - * @param wgr response details - */ -typedef void -(*TALER_MERCHANT_GetPrivateWebhooksCallback)( - TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetPrivateWebhooksResponse *wgr); - - -/** - * Start GET /private/webhooks operation. - * - * @param[in,out] gpwh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_private_webhooks_start ( - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh, - TALER_MERCHANT_GetPrivateWebhooksCallback cb, - TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /private/webhooks operation. This function must not be - * called by clients after the TALER_MERCHANT_GetPrivateWebhooksCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpwh operation to cancel - */ -void -TALER_MERCHANT_get_private_webhooks_cancel ( - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh); - - -#endif /* _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-private-webhooks.h b/src/include/taler/taler-merchant/get-private-webhooks.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/get-private-webhooks.h - * @brief C interface for GET /private/webhooks of the merchant backend + * @brief C interface for the GET /private/webhooks endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_H @@ -28,13 +28,13 @@ /** * Handle for a GET /private/webhooks request. */ -struct TALER_MERCHANT_WebhooksGetHandle; +struct TALER_MERCHANT_GetPrivateWebhooksHandle; /** * Entry for one webhook. */ -struct TALER_MERCHANT_WebhookEntry +struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry { /** @@ -53,7 +53,7 @@ struct TALER_MERCHANT_WebhookEntry /** * Response details for a GET /private/webhooks request. */ -struct TALER_MERCHANT_WebhooksGetResponse +struct TALER_MERCHANT_GetPrivateWebhooksResponse { /** @@ -81,7 +81,7 @@ struct TALER_MERCHANT_WebhooksGetResponse /** * Array of webhook entries. */ - const struct TALER_MERCHANT_WebhookEntry *webhooks; + const struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry *webhooks; } ok; @@ -91,41 +91,66 @@ struct TALER_MERCHANT_WebhooksGetResponse /** + * Set up GET /private/webhooks operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @return handle to operation + */ +struct TALER_MERCHANT_GetPrivateWebhooksHandle * +TALER_MERCHANT_get_private_webhooks_create ( + struct GNUNET_CURL_Context *ctx, + const char *url); + + +#ifndef TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetPrivateWebhooksCallback. + */ +#define TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE */ + +/** * Callback for a GET /private/webhooks request. * * @param cls closure * @param wgr response details */ typedef void -(*TALER_MERCHANT_WebhooksGetCallback)( - void *cls, - const struct TALER_MERCHANT_WebhooksGetResponse *wgr); +(*TALER_MERCHANT_GetPrivateWebhooksCallback)( + TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetPrivateWebhooksResponse *wgr); /** - * Issue a GET /private/webhooks request. + * Start GET /private/webhooks operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param cb callback to invoke with the result + * @param[in,out] gpwh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_WebhooksGetHandle * -TALER_MERCHANT_webhooks_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_WebhooksGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_private_webhooks_start ( + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh, + TALER_MERCHANT_GetPrivateWebhooksCallback cb, + TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /private/webhooks request. + * Cancel GET /private/webhooks operation. This function must not be + * called by clients after the TALER_MERCHANT_GetPrivateWebhooksCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] wgh handle to cancel + * @param[in] gpwh operation to cancel */ void -TALER_MERCHANT_webhooks_get_cancel ( - struct TALER_MERCHANT_WebhooksGetHandle *wgh); +TALER_MERCHANT_get_private_webhooks_cancel ( + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh); -#endif +#endif /* _TALER_MERCHANT__GET_PRIVATE_WEBHOOKS_H */ diff --git a/src/include/taler/taler-merchant/get-products-IMAGE_HASH-image-new.h b/src/include/taler/taler-merchant/get-products-IMAGE_HASH-image-new.h @@ -1,135 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-products-IMAGE_HASH-image-new.h - * @brief C interface for GET /products/$IMAGE_HASH/image of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_PRODUCTS_IMAGE_HASH_IMAGE_NEW_H -#define _TALER_MERCHANT__GET_PRODUCTS_IMAGE_HASH_IMAGE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /products/$IMAGE_HASH/image request. - */ -struct TALER_MERCHANT_GetProductsImageHandle; - - -/** - * Response details for a GET /products/$IMAGE_HASH/image request. - */ -struct TALER_MERCHANT_GetProductsImageResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Image data (a data URI). - */ - const char *image; - - } ok; - - } details; - -}; - - -/** - * Set up GET /products/$IMAGE_HASH/image operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param image_hash hash identifying the image to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetProductsImageHandle * -TALER_MERCHANT_get_products_image_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *image_hash); - - -#ifndef TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetProductsImageCallback. - */ -#define TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE */ - -/** - * Callback for a GET /products/$IMAGE_HASH/image request. - * - * @param cls closure - * @param pgr response details - */ -typedef void -(*TALER_MERCHANT_GetProductsImageCallback)( - TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetProductsImageResponse *pgr); - - -/** - * Start GET /products/$IMAGE_HASH/image operation. - * - * @param[in,out] gpi operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_products_image_start ( - struct TALER_MERCHANT_GetProductsImageHandle *gpi, - TALER_MERCHANT_GetProductsImageCallback cb, - TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /products/$IMAGE_HASH/image operation. This function - * must not be called by clients after the - * TALER_MERCHANT_GetProductsImageCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gpi operation to cancel - */ -void -TALER_MERCHANT_get_products_image_cancel ( - struct TALER_MERCHANT_GetProductsImageHandle *gpi); - - -#endif /* _TALER_MERCHANT__GET_PRODUCTS_IMAGE_HASH_IMAGE_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-products-IMAGE_HASH-image.h b/src/include/taler/taler-merchant/get-products-IMAGE_HASH-image.h @@ -28,13 +28,13 @@ /** * Handle for a GET /products/$IMAGE_HASH/image request. */ -struct TALER_MERCHANT_ProductImageGetHandle; +struct TALER_MERCHANT_GetProductsImageHandle; /** * Response details for a GET /products/$IMAGE_HASH/image request. */ -struct TALER_MERCHANT_ProductImageGetResponse +struct TALER_MERCHANT_GetProductsImageResponse { /** @@ -67,44 +67,69 @@ struct TALER_MERCHANT_ProductImageGetResponse /** + * Set up GET /products/$IMAGE_HASH/image operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param image_hash hash identifying the image to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetProductsImageHandle * +TALER_MERCHANT_get_products_image_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *image_hash); + + +#ifndef TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetProductsImageCallback. + */ +#define TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE */ + +/** * Callback for a GET /products/$IMAGE_HASH/image request. * * @param cls closure * @param pgr response details */ typedef void -(*TALER_MERCHANT_ProductImageGetCallback)( - void *cls, - const struct TALER_MERCHANT_ProductImageGetResponse *pgr); +(*TALER_MERCHANT_GetProductsImageCallback)( + TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetProductsImageResponse *pgr); /** - * Issue a GET /products/$IMAGE_HASH/image request. + * Start GET /products/$IMAGE_HASH/image operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param image_hash hash identifying the image to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gpi operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductImageGetHandle * -TALER_MERCHANT_product_image_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *image_hash, - TALER_MERCHANT_ProductImageGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_products_image_start ( + struct TALER_MERCHANT_GetProductsImageHandle *gpi, + TALER_MERCHANT_GetProductsImageCallback cb, + TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /products/$IMAGE_HASH/image request. + * Cancel GET /products/$IMAGE_HASH/image operation. This function + * must not be called by clients after the + * TALER_MERCHANT_GetProductsImageCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] pigh handle to cancel + * @param[in] gpi operation to cancel */ void -TALER_MERCHANT_product_image_get_cancel ( - struct TALER_MERCHANT_ProductImageGetHandle *pigh); +TALER_MERCHANT_get_products_image_cancel ( + struct TALER_MERCHANT_GetProductsImageHandle *gpi); -#endif +#endif /* _TALER_MERCHANT__GET_PRODUCTS_IMAGE_HASH_IMAGE_H */ diff --git a/src/include/taler/taler-merchant/get-templates-TEMPLATE_ID-new.h b/src/include/taler/taler-merchant/get-templates-TEMPLATE_ID-new.h @@ -1,135 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/get-templates-TEMPLATE_ID-new.h - * @brief C interface for GET /templates/$TEMPLATE_ID (wallet-facing) of the merchant backend - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__GET_TEMPLATES_TEMPLATE_ID_NEW_H -#define _TALER_MERCHANT__GET_TEMPLATES_TEMPLATE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a GET /templates/$TEMPLATE_ID request (wallet-facing). - */ -struct TALER_MERCHANT_GetTemplatesHandle; - - -/** - * Response details for a GET /templates/$TEMPLATE_ID request (wallet-facing). - */ -struct TALER_MERCHANT_GetTemplatesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Template contract (JSON). - */ - const json_t *template_contract; - - } ok; - - } details; - -}; - - -/** - * Set up GET /templates/$TEMPLATE_ID operation (wallet-facing). - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param template_id identifier of the template to retrieve - * @return handle to operation - */ -struct TALER_MERCHANT_GetTemplatesHandle * -TALER_MERCHANT_get_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id); - - -#ifndef TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_GetTemplatesCallback. - */ -#define TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE */ - -/** - * Callback for a GET /templates/$TEMPLATE_ID request (wallet-facing). - * - * @param cls closure - * @param wtgr response details - */ -typedef void -(*TALER_MERCHANT_GetTemplatesCallback)( - TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_GetTemplatesResponse *wtgr); - - -/** - * Start GET /templates/$TEMPLATE_ID operation (wallet-facing). - * - * @param[in,out] gth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_get_templates_start ( - struct TALER_MERCHANT_GetTemplatesHandle *gth, - TALER_MERCHANT_GetTemplatesCallback cb, - TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel GET /templates/$TEMPLATE_ID operation (wallet-facing). - * This function must not be called by clients after the - * TALER_MERCHANT_GetTemplatesCallback has been invoked - * (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] gth operation to cancel - */ -void -TALER_MERCHANT_get_templates_cancel ( - struct TALER_MERCHANT_GetTemplatesHandle *gth); - - -#endif /* _TALER_MERCHANT__GET_TEMPLATES_TEMPLATE_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/get-templates-TEMPLATE_ID.h b/src/include/taler/taler-merchant/get-templates-TEMPLATE_ID.h @@ -28,13 +28,13 @@ /** * Handle for a GET /templates/$TEMPLATE_ID request (wallet-facing). */ -struct TALER_MERCHANT_WalletTemplateGetHandle; +struct TALER_MERCHANT_GetTemplatesHandle; /** * Response details for a GET /templates/$TEMPLATE_ID request (wallet-facing). */ -struct TALER_MERCHANT_WalletTemplateGetResponse +struct TALER_MERCHANT_GetTemplatesResponse { /** @@ -67,44 +67,69 @@ struct TALER_MERCHANT_WalletTemplateGetResponse /** + * Set up GET /templates/$TEMPLATE_ID operation (wallet-facing). + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param template_id identifier of the template to retrieve + * @return handle to operation + */ +struct TALER_MERCHANT_GetTemplatesHandle * +TALER_MERCHANT_get_templates_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *template_id); + + +#ifndef TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_GetTemplatesCallback. + */ +#define TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE */ + +/** * Callback for a GET /templates/$TEMPLATE_ID request (wallet-facing). * * @param cls closure * @param wtgr response details */ typedef void -(*TALER_MERCHANT_WalletTemplateGetCallback)( - void *cls, - const struct TALER_MERCHANT_WalletTemplateGetResponse *wtgr); +(*TALER_MERCHANT_GetTemplatesCallback)( + TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_GetTemplatesResponse *wtgr); /** - * Issue a GET /templates/$TEMPLATE_ID request (wallet-facing). + * Start GET /templates/$TEMPLATE_ID operation (wallet-facing). * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param template_id identifier of the template to retrieve - * @param cb callback to invoke with the result + * @param[in,out] gth operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_WalletTemplateGetHandle * -TALER_MERCHANT_wallet_template_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - TALER_MERCHANT_WalletTemplateGetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_get_templates_start ( + struct TALER_MERCHANT_GetTemplatesHandle *gth, + TALER_MERCHANT_GetTemplatesCallback cb, + TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cb_cls); /** - * Cancel a GET /templates/$TEMPLATE_ID request (wallet-facing). + * Cancel GET /templates/$TEMPLATE_ID operation (wallet-facing). + * This function must not be called by clients after the + * TALER_MERCHANT_GetTemplatesCallback has been invoked + * (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tgh handle to cancel + * @param[in] gth operation to cancel */ void -TALER_MERCHANT_wallet_template_get_cancel ( - struct TALER_MERCHANT_WalletTemplateGetHandle *tgh); +TALER_MERCHANT_get_templates_cancel ( + struct TALER_MERCHANT_GetTemplatesHandle *gth); -#endif +#endif /* _TALER_MERCHANT__GET_TEMPLATES_TEMPLATE_ID_H */ diff --git a/src/include/taler/taler-merchant/patch-management-instances-INSTANCE-new.h b/src/include/taler/taler-merchant/patch-management-instances-INSTANCE-new.h @@ -1,123 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-management-instances-INSTANCE-new.h - * @brief C interface for PATCH /management/instances/$INSTANCE - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_MANAGEMENT_INSTANCES_INSTANCE_NEW_H -#define _TALER_MERCHANT__PATCH_MANAGEMENT_INSTANCES_INSTANCE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a PATCH /management/instances/$INSTANCE operation. - */ -struct TALER_MERCHANT_PatchManagementInstancesHandle; - - -/** - * Set up PATCH /management/instances/$INSTANCE operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param instance_id identifier of the instance to patch - * @param name new human-readable name - * @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 * -TALER_MERCHANT_patch_management_instances_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - 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); - - -/** - * Response details for a PATCH /management/instances/$INSTANCE request. - */ -struct TALER_MERCHANT_PatchManagementInstancesResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchManagementInstancesCallback. - */ -#define TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /management/instances/$INSTANCE request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchManagementInstancesCallback)( - TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchManagementInstancesResponse *result); - - -/** - * Start PATCH /management/instances/$INSTANCE operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_management_instances_start ( - struct TALER_MERCHANT_PatchManagementInstancesHandle *handle, - TALER_MERCHANT_PatchManagementInstancesCallback cb, - TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /management/instances/$INSTANCE operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_patch_management_instances_cancel ( - struct TALER_MERCHANT_PatchManagementInstancesHandle *handle); - - -#endif /* _TALER_MERCHANT__PATCH_MANAGEMENT_INSTANCES_INSTANCE_NEW_H */ diff --git a/src/include/taler/taler-merchant/patch-management-instances-INSTANCE.h b/src/include/taler/taler-merchant/patch-management-instances-INSTANCE.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-management-instances-INSTANCE.h - * @brief C interface for PATCH /management/instances/$INSTANCE of the merchant backend + * @brief C interface for PATCH /management/instances/$INSTANCE * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_MANAGEMENT_INSTANCES_INSTANCE_H @@ -26,44 +26,31 @@ /** - * Handle for a PATCH /management/instances/$INSTANCE request. + * Handle for a PATCH /management/instances/$INSTANCE operation. */ -struct TALER_MERCHANT_InstancePatchHandle; +struct TALER_MERCHANT_PatchManagementInstancesHandle; /** - * Callback for a PATCH /management/instances/$INSTANCE request. - * - * @param cls closure - * @param hr HTTP response details - */ -typedef void -(*TALER_MERCHANT_InstancePatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); - - -/** - * Issue a PATCH /management/instances/$INSTANCE request. + * Set up PATCH /management/instances/$INSTANCE operation. + * Note that you must explicitly start the operation after setup. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param instance_id identifier of the instance to patch * @param name new human-readable name - * @param address new address (JSON), or NULL to keep unchanged - * @param jurisdiction new jurisdiction (JSON), or NULL to keep unchanged + * @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 - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation, NULL on error */ -struct TALER_MERCHANT_InstancePatchHandle * -TALER_MERCHANT_instance_patch ( +struct TALER_MERCHANT_PatchManagementInstancesHandle * +TALER_MERCHANT_patch_management_instances_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, const char *name, const json_t *address, @@ -71,19 +58,66 @@ TALER_MERCHANT_instance_patch ( 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, - TALER_MERCHANT_InstancePatchCallback cb, - void *cb_cls); + struct GNUNET_TIME_Relative default_refund_delay); + + +/** + * Response details for a PATCH /management/instances/$INSTANCE request. + */ +struct TALER_MERCHANT_PatchManagementInstancesResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchManagementInstancesCallback. + */ +#define TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE */ + +/** + * Callback for a PATCH /management/instances/$INSTANCE request. + * + * @param cls closure + * @param result response details + */ +typedef void +(*TALER_MERCHANT_PatchManagementInstancesCallback)( + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchManagementInstancesResponse *result); + + +/** + * Start PATCH /management/instances/$INSTANCE operation. + * + * @param[in,out] handle operation to start + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_patch_management_instances_start ( + struct TALER_MERCHANT_PatchManagementInstancesHandle *handle, + TALER_MERCHANT_PatchManagementInstancesCallback cb, + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /management/instances/$INSTANCE request. + * Cancel PATCH /management/instances/$INSTANCE operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] iph handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_instance_patch_cancel ( - struct TALER_MERCHANT_InstancePatchHandle *iph); +TALER_MERCHANT_patch_management_instances_cancel ( + struct TALER_MERCHANT_PatchManagementInstancesHandle *handle); -#endif +#endif /* _TALER_MERCHANT__PATCH_MANAGEMENT_INSTANCES_INSTANCE_H */ diff --git a/src/include/taler/taler-merchant/patch-private-accounts-H_WIRE-new.h b/src/include/taler/taler-merchant/patch-private-accounts-H_WIRE-new.h @@ -1,254 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-accounts-H_WIRE-new.h - * @brief C interface for PATCH /private/accounts/$H_WIRE - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_ACCOUNTS_H_WIRE_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_ACCOUNTS_H_WIRE_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the PATCH /private/accounts/$H_WIRE request. - */ -enum TALER_MERCHANT_PatchPrivateAccountOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_END = 0, - - /** - * Set the credit facade URL. - */ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL, - - /** - * Set the credit facade credentials (JSON). - */ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS - -}; - - -/** - * Value for an option for the PATCH /private/accounts/$H_WIRE request. - */ -struct TALER_MERCHANT_PatchPrivateAccountOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PatchPrivateAccountOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL. - */ - const char *credit_facade_url; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS. - */ - const json_t *credit_facade_credentials; - - } details; - -}; - - -/** - * Handle for a PATCH /private/accounts/$H_WIRE operation. - */ -struct TALER_MERCHANT_PatchPrivateAccountHandle; - - -/** - * Set up PATCH /private/accounts/$H_WIRE operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param h_wire hash of the wire details identifying the account - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_PatchPrivateAccountHandle * -TALER_MERCHANT_patch_private_account_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_MerchantWireHashP *h_wire); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PatchPrivateAccountOptionValue - */ -#define TALER_MERCHANT_patch_private_account_option_end_() \ - (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_END \ - } - -/** - * Set credit facade URL. - * - * @param u credit facade URL to set - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateAccountOptionValue - */ -#define TALER_MERCHANT_patch_private_account_option_credit_facade_url(u) \ - (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL, \ - .details.credit_facade_url = (u) \ - } - -/** - * Set credit facade credentials. - * - * @param c credit facade credentials (JSON) to set - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateAccountOptionValue - */ -#define TALER_MERCHANT_patch_private_account_option_credit_facade_credentials(c) \ - (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS, \ - .details.credit_facade_credentials = (c) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param pah 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_account_set_options_ ( - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, - unsigned int num_options, - const struct TALER_MERCHANT_PatchPrivateAccountOptionValue *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_account_set_options ( - * pah, - * TALER_MERCHANT_patch_private_account_option_credit_facade_url ( - * "https://example.com/facade")); - * - * @param pah the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_patch_private_account_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_patch_private_account_set_options(pah,...) \ - TALER_MERCHANT_patch_private_account_set_options_ ( \ - pah, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PatchPrivateAccountOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_patch_private_account_option_end_ () } \ - )) - - -/** - * Response details for a PATCH /private/accounts/$H_WIRE request. - */ -struct TALER_MERCHANT_PatchPrivateAccountResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateAccountCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/accounts/$H_WIRE request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateAccountCallback)( - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateAccountResponse *result); - - -/** - * Start PATCH /private/accounts/$H_WIRE operation. - * - * @param[in,out] pah operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_account_start ( - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, - TALER_MERCHANT_PatchPrivateAccountCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/accounts/$H_WIRE operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] pah operation to cancel - */ -void -TALER_MERCHANT_patch_private_account_cancel ( - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_ACCOUNTS_H_WIRE_NEW_H */ 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 @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-accounts-H_WIRE.h - * @brief C interface for PATCH /private/accounts/$H_WIRE of the merchant backend + * @brief C interface for PATCH /private/accounts/$H_WIRE * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_ACCOUNTS_H_WIRE_H @@ -26,54 +26,229 @@ /** - * Handle for a PATCH /private/accounts/$H_WIRE request. + * Possible options we can set for the PATCH /private/accounts/$H_WIRE request. */ -struct TALER_MERCHANT_AccountPatchHandle; +enum TALER_MERCHANT_PatchPrivateAccountOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_END = 0, + + /** + * Set the credit facade URL. + */ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL, + + /** + * Set the credit facade credentials (JSON). + */ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS + +}; + + +/** + * Value for an option for the PATCH /private/accounts/$H_WIRE request. + */ +struct TALER_MERCHANT_PatchPrivateAccountOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchPrivateAccountOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL. + */ + const char *credit_facade_url; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS. + */ + const json_t *credit_facade_credentials; + + } details; + +}; + + +/** + * Handle for a PATCH /private/accounts/$H_WIRE operation. + */ +struct TALER_MERCHANT_PatchPrivateAccountHandle; + + +/** + * Set up PATCH /private/accounts/$H_WIRE operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param h_wire hash of the wire details identifying the account + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_PatchPrivateAccountHandle * +TALER_MERCHANT_patch_private_account_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_MerchantWireHashP *h_wire); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PatchPrivateAccountOptionValue + */ +#define TALER_MERCHANT_patch_private_account_option_end_() \ + (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_END \ + } + +/** + * Set credit facade URL. + * + * @param u credit facade URL to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateAccountOptionValue + */ +#define TALER_MERCHANT_patch_private_account_option_credit_facade_url(u) \ + (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_URL, \ + .details.credit_facade_url = (u) \ + } + +/** + * Set credit facade credentials. + * + * @param c credit facade credentials (JSON) to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateAccountOptionValue + */ +#define TALER_MERCHANT_patch_private_account_option_credit_facade_credentials(c) \ + (const struct TALER_MERCHANT_PatchPrivateAccountOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS, \ + .details.credit_facade_credentials = (c) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param pah 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_account_set_options_ ( + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateAccountOptionValue *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_account_set_options ( + * pah, + * TALER_MERCHANT_patch_private_account_option_credit_facade_url ( + * "https://example.com/facade")); + * + * @param pah the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_patch_private_account_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_private_account_set_options(pah,...) \ + TALER_MERCHANT_patch_private_account_set_options_ ( \ + pah, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchPrivateAccountOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_private_account_option_end_ () } \ + )) /** + * Response details for a PATCH /private/accounts/$H_WIRE request. + */ +struct TALER_MERCHANT_PatchPrivateAccountResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateAccountCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE */ + +/** * Callback for a PATCH /private/accounts/$H_WIRE request. * * @param cls closure - * @param hr HTTP response details + * @param result response details */ typedef void -(*TALER_MERCHANT_AccountPatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_PatchPrivateAccountCallback)( + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateAccountResponse *result); /** - * Issue a PATCH /private/accounts/$H_WIRE request to update a wire account. + * Start PATCH /private/accounts/$H_WIRE operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param h_wire hash of the wire details identifying the account - * @param credit_facade_url new URL of the credit facade, or NULL - * @param credit_facade_credentials new credentials (JSON), or NULL - * @param cb callback to invoke with the result + * @param[in,out] pah operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_AccountPatchHandle * -TALER_MERCHANT_account_patch ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MerchantWireHashP *h_wire, - const char *credit_facade_url, - const json_t *credit_facade_credentials, - TALER_MERCHANT_AccountPatchCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_account_start ( + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, + TALER_MERCHANT_PatchPrivateAccountCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/accounts/$H_WIRE request. + * Cancel PATCH /private/accounts/$H_WIRE operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tph handle to cancel + * @param[in] pah operation to cancel */ void -TALER_MERCHANT_account_patch_cancel ( - struct TALER_MERCHANT_AccountPatchHandle *tph); +TALER_MERCHANT_patch_private_account_cancel ( + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_ACCOUNTS_H_WIRE_H */ diff --git a/src/include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h b/src/include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h @@ -1,113 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h - * @brief C interface for PATCH /private/orders/$ORDER_ID/forget - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_ORDERS_ORDER_ID_FORGET_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_ORDERS_ORDER_ID_FORGET_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a PATCH /private/orders/$ORDER_ID/forget operation. - */ -struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle; - - -/** - * Set up PATCH /private/orders/$ORDER_ID/forget operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order - * @param fields_length number of field paths in @a fields - * @param fields array of JSON pointer paths to redact - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle * -TALER_MERCHANT_patch_private_orders_forget_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - unsigned int fields_length, - const char *fields[static fields_length]); - - -/** - * Response details for a PATCH /private/orders/$ORDER_ID/forget request. - */ -struct TALER_MERCHANT_PatchPrivateOrdersForgetResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateOrdersForgetCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/orders/$ORDER_ID/forget request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateOrdersForgetCallback)( - TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateOrdersForgetResponse *result); - - -/** - * Start PATCH /private/orders/$ORDER_ID/forget operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_orders_forget_start ( - struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *handle, - TALER_MERCHANT_PatchPrivateOrdersForgetCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/orders/$ORDER_ID/forget operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_patch_private_orders_forget_cancel ( - struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *handle); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_ORDERS_ORDER_ID_FORGET_NEW_H */ diff --git a/src/include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h b/src/include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h - * @brief C interface for PATCH /private/orders/$ORDER_ID/forget of the merchant backend + * @brief C interface for PATCH /private/orders/$ORDER_ID/forget * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_ORDERS_ORDER_ID_FORGET_H @@ -26,55 +26,88 @@ /** - * Handle for a PATCH /private/orders/$ORDER_ID/forget request. + * Handle for a PATCH /private/orders/$ORDER_ID/forget operation. */ -struct TALER_MERCHANT_OrderForgetHandle; +struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle; /** + * Set up PATCH /private/orders/$ORDER_ID/forget operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order + * @param fields_length number of field paths in @a fields + * @param fields array of JSON pointer paths to redact + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle * +TALER_MERCHANT_patch_private_orders_forget_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + unsigned int fields_length, + const char *fields[static fields_length]); + + +/** + * Response details for a PATCH /private/orders/$ORDER_ID/forget request. + */ +struct TALER_MERCHANT_PatchPrivateOrdersForgetResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateOrdersForgetCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE */ + +/** * Callback for a PATCH /private/orders/$ORDER_ID/forget request. * * @param cls closure - * @param hr HTTP response details + * @param result response details */ typedef void -(*TALER_MERCHANT_ForgetCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_PatchPrivateOrdersForgetCallback)( + TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateOrdersForgetResponse *result); /** - * Issue a PATCH /private/orders/$ORDER_ID/forget request to redact - * specific fields from the contract terms. + * Start PATCH /private/orders/$ORDER_ID/forget operation. * - * @param ctx CURL context to use - * @param merchant_url base URL of the merchant backend - * @param order_id identifier of the order - * @param fields_length number of field paths in @a fields - * @param fields array of JSON pointer paths to redact - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderForgetHandle * -TALER_MERCHANT_order_forget ( - struct GNUNET_CURL_Context *ctx, - const char *merchant_url, - const char *order_id, - unsigned int fields_length, - const char *fields[static fields_length], - TALER_MERCHANT_ForgetCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_orders_forget_start ( + struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *handle, + TALER_MERCHANT_PatchPrivateOrdersForgetCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/orders/$ORDER_ID/forget request. + * Cancel PATCH /private/orders/$ORDER_ID/forget operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] ofh handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_order_forget_cancel ( - struct TALER_MERCHANT_OrderForgetHandle *ofh); +TALER_MERCHANT_patch_private_orders_forget_cancel ( + struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *handle); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_ORDERS_ORDER_ID_FORGET_H */ diff --git a/src/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h b/src/include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h @@ -1,117 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h - * @brief C interface for PATCH /private/otp-devices/$DEVICE_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a PATCH /private/otp-devices/$DEVICE_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle; - - -/** - * Set up PATCH /private/otp-devices/$DEVICE_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param otp_device_id identifier of the OTP device to update - * @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 * -TALER_MERCHANT_patch_private_otp_device_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id, - const char *otp_device_description, - const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm mca, - uint64_t otp_ctr); - - -/** - * Response details for a PATCH /private/otp-devices/$DEVICE_ID request. - */ -struct TALER_MERCHANT_PatchPrivateOtpDeviceResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateOtpDeviceCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/otp-devices/$DEVICE_ID request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateOtpDeviceCallback)( - TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateOtpDeviceResponse *result); - - -/** - * Start PATCH /private/otp-devices/$DEVICE_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_otp_device_start ( - struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *handle, - TALER_MERCHANT_PatchPrivateOtpDeviceCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/otp-devices/$DEVICE_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_patch_private_otp_device_cancel ( - struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *handle); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_OTP_DEVICES_DEVICE_ID_NEW_H */ 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 @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h - * @brief C interface for PATCH /private/otp-devices/$DEVICE_ID of the merchant backend + * @brief C interface for PATCH /private/otp-devices/$DEVICE_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_OTP_DEVICES_DEVICE_ID_H @@ -26,58 +26,92 @@ /** - * Handle for a PATCH /private/otp-devices/$DEVICE_ID request. + * Handle for a PATCH /private/otp-devices/$DEVICE_ID operation. */ -struct TALER_MERCHANT_OtpDevicePatchHandle; +struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle; /** - * Callback for a PATCH /private/otp-devices/$DEVICE_ID request. - * - * @param cls closure - * @param hr HTTP response details - */ -typedef void -(*TALER_MERCHANT_OtpDevicePatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); - - -/** - * Issue a PATCH /private/otp-devices/$DEVICE_ID request to update an OTP device. + * Set up PATCH /private/otp-devices/$DEVICE_ID operation. + * Note that you must explicitly start the operation after setup. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param otp_device_id identifier of the OTP device to update * @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) - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation, NULL on error */ -struct TALER_MERCHANT_OtpDevicePatchHandle * -TALER_MERCHANT_otp_device_patch ( +struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle * +TALER_MERCHANT_patch_private_otp_device_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *otp_device_id, const char *otp_device_description, const char *otp_key, enum TALER_MerchantConfirmationAlgorithm mca, - uint64_t otp_ctr, - TALER_MERCHANT_OtpDevicePatchCallback cb, - void *cb_cls); + uint64_t otp_ctr); + + +/** + * Response details for a PATCH /private/otp-devices/$DEVICE_ID request. + */ +struct TALER_MERCHANT_PatchPrivateOtpDeviceResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateOtpDeviceCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE */ + +/** + * Callback for a PATCH /private/otp-devices/$DEVICE_ID request. + * + * @param cls closure + * @param result response details + */ +typedef void +(*TALER_MERCHANT_PatchPrivateOtpDeviceCallback)( + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateOtpDeviceResponse *result); + + +/** + * Start PATCH /private/otp-devices/$DEVICE_ID operation. + * + * @param[in,out] handle operation to start + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_otp_device_start ( + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *handle, + TALER_MERCHANT_PatchPrivateOtpDeviceCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/otp-devices/$DEVICE_ID request. + * Cancel PATCH /private/otp-devices/$DEVICE_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tph handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_otp_device_patch_cancel ( - struct TALER_MERCHANT_OtpDevicePatchHandle *tph); +TALER_MERCHANT_patch_private_otp_device_cancel ( + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *handle); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_OTP_DEVICES_DEVICE_ID_H */ diff --git a/src/include/taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h b/src/include/taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h @@ -1,336 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h - * @brief C interface for PATCH /private/products/$PRODUCT_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the PATCH /private/products/$PRODUCT_ID request. - */ -enum TALER_MERCHANT_PatchPrivateProductOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_END = 0, - - /** - * Set unit prices array (for patch2 variant with full unit/fraction support). - */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES, - - /** - * Set fractional part of total stock. - */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC, - - /** - * Set whether fractional quantities are allowed. - */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION, - - /** - * Set precision level for fractions. - */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL - -}; - - -/** - * Value for an option for the PATCH /private/products/$PRODUCT_ID request. - */ -struct TALER_MERCHANT_PatchPrivateProductOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PatchPrivateProductOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES. - */ - struct - { - /** - * Array of unit prices. - */ - const struct TALER_Amount *unit_prices; - - /** - * Number of prices in @e unit_prices. - */ - size_t unit_price_len; - - } unit_prices; - - /** - * Value if @e option is - * #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; - - } details; - -}; - - -/** - * Handle for a PATCH /private/products/$PRODUCT_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateProductHandle; - - -/** - * Set up PATCH /private/products/$PRODUCT_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @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 - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_PatchPrivateProductHandle * -TALER_MERCHANT_patch_private_product_create ( - struct GNUNET_CURL_Context *ctx, - 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); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PatchPrivateProductOptionValue - */ -#define TALER_MERCHANT_patch_private_product_option_end_() \ - (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_END \ - } - -/** - * Set unit prices array. - * - * @param p pointer to array of unit prices - * @param l number of prices in the array - * @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) } \ - } - -/** - * Set fractional part of total stock. - * - * @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) \ - } - -/** - * Set whether fractional quantities are allowed. - * - * @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) \ - } - -/** - * Set precision level for fractions. - * - * @param p precision level value - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateProductOptionValue - */ -#define TALER_MERCHANT_patch_private_product_option_unit_precision_level(p) \ - (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL, \ - .details.unit_precision_level = (p) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param pph 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_product_set_options_ ( - struct TALER_MERCHANT_PatchPrivateProductHandle *pph, - unsigned int num_options, - const struct TALER_MERCHANT_PatchPrivateProductOptionValue *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_product_set_options ( - * pph, - * TALER_MERCHANT_patch_private_product_option_total_stock_frac (500), - * TALER_MERCHANT_patch_private_product_option_unit_allow_fraction (true)); - * - * @param pph the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_patch_private_product_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_patch_private_product_set_options(pph,...) \ - TALER_MERCHANT_patch_private_product_set_options_ ( \ - pph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PatchPrivateProductOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_patch_private_product_option_end_ () } \ - )) - - -/** - * Response details for a PATCH /private/products/$PRODUCT_ID request. - */ -struct TALER_MERCHANT_PatchPrivateProductResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateProductCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/products/$PRODUCT_ID request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateProductCallback)( - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateProductResponse *result); - - -/** - * Start PATCH /private/products/$PRODUCT_ID operation. - * - * @param[in,out] pph operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_product_start ( - struct TALER_MERCHANT_PatchPrivateProductHandle *pph, - TALER_MERCHANT_PatchPrivateProductCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/products/$PRODUCT_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] pph operation to cancel - */ -void -TALER_MERCHANT_patch_private_product_cancel ( - struct TALER_MERCHANT_PatchPrivateProductHandle *pph); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_PRODUCTS_PRODUCT_ID_NEW_H */ 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 @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-products-PRODUCT_ID.h - * @brief C interface for PATCH /private/products/$PRODUCT_ID of the merchant backend + * @brief C interface for PATCH /private/products/$PRODUCT_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_PRODUCTS_PRODUCT_ID_H @@ -26,28 +26,109 @@ /** - * Handle for a PATCH /private/products/$PRODUCT_ID request. + * Possible options we can set for the PATCH /private/products/$PRODUCT_ID request. */ -struct TALER_MERCHANT_ProductPatchHandle; +enum TALER_MERCHANT_PatchPrivateProductOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_END = 0, + + /** + * Set unit prices array (for patch2 variant with full unit/fraction support). + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES, + + /** + * Set fractional part of total stock. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_TOTAL_STOCK_FRAC, + + /** + * Set whether fractional quantities are allowed. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_ALLOW_FRACTION, + + /** + * Set precision level for fractions. + */ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL + +}; /** - * Callback for a PATCH /private/products/$PRODUCT_ID request. - * - * @param cls closure - * @param hr HTTP response details + * Value for an option for the PATCH /private/products/$PRODUCT_ID request. */ -typedef void -(*TALER_MERCHANT_ProductPatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +struct TALER_MERCHANT_PatchPrivateProductOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchPrivateProductOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRICES. + */ + struct + { + /** + * Array of unit prices. + */ + const struct TALER_Amount *unit_prices; + + /** + * Number of prices in @e unit_prices. + */ + size_t unit_price_len; + + } unit_prices; + + /** + * Value if @e option is + * #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; + + } details; + +}; + + +/** + * Handle for a PATCH /private/products/$PRODUCT_ID operation. + */ +struct TALER_MERCHANT_PatchPrivateProductHandle; /** - * Issue a PATCH /private/products/$PRODUCT_ID request (simple form). + * Set up PATCH /private/products/$PRODUCT_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @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) @@ -59,14 +140,12 @@ typedef void * @param total_lost total units lost/expired * @param address storage location (JSON) * @param next_restock expected restock time - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation, NULL on error */ -struct TALER_MERCHANT_ProductPatchHandle * -TALER_MERCHANT_product_patch ( +struct TALER_MERCHANT_PatchPrivateProductHandle * +TALER_MERCHANT_patch_private_product_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *product_id, const char *description, const json_t *description_i18n, @@ -77,66 +156,181 @@ TALER_MERCHANT_product_patch ( int64_t total_stock, uint64_t total_lost, const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - TALER_MERCHANT_ProductPatchCallback cb, - void *cb_cls); + struct GNUNET_TIME_Timestamp next_restock); /** - * Issue a PATCH /private/products/$PRODUCT_ID request with full unit/fraction support. + * Terminate the list of the options. * - * @param ctx CURL context to use - * @param backend_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 unit_prices array of unit prices - * @param unit_price_len number of prices in @a unit_prices - * @param image new base64-encoded image - * @param taxes new tax information (JSON array) - * @param total_stock integer part of total stock (-1 for unlimited) - * @param total_stock_frac fractional part of total stock - * @param unit_allow_fraction whether fractional quantities are allowed - * @param unit_precision_level precision level for fractions, or NULL - * @param total_lost total units lost/expired - * @param address storage location (JSON) - * @param next_restock expected restock time - * @param cb callback to invoke with the result + * @return the terminating object of struct TALER_MERCHANT_PatchPrivateProductOptionValue + */ +#define TALER_MERCHANT_patch_private_product_option_end_() \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_END \ + } + +/** + * Set unit prices array. + * + * @param p pointer to array of unit prices + * @param l number of prices in the array + * @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) } \ + } + +/** + * Set fractional part of total stock. + * + * @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) \ + } + +/** + * Set whether fractional quantities are allowed. + * + * @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) \ + } + +/** + * Set precision level for fractions. + * + * @param p precision level value + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateProductOptionValue + */ +#define TALER_MERCHANT_patch_private_product_option_unit_precision_level(p) \ + (const struct TALER_MERCHANT_PatchPrivateProductOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_OPTION_UNIT_PRECISION_LEVEL, \ + .details.unit_precision_level = (p) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param pph 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_product_set_options_ ( + struct TALER_MERCHANT_PatchPrivateProductHandle *pph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateProductOptionValue *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_product_set_options ( + * pph, + * TALER_MERCHANT_patch_private_product_option_total_stock_frac (500), + * TALER_MERCHANT_patch_private_product_option_unit_allow_fraction (true)); + * + * @param pph the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_patch_private_product_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_private_product_set_options(pph,...) \ + TALER_MERCHANT_patch_private_product_set_options_ ( \ + pph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchPrivateProductOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_private_product_option_end_ () } \ + )) + + +/** + * Response details for a PATCH /private/products/$PRODUCT_ID request. + */ +struct TALER_MERCHANT_PatchPrivateProductResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateProductCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE */ + +/** + * Callback for a PATCH /private/products/$PRODUCT_ID request. + * + * @param cls closure + * @param result response details + */ +typedef void +(*TALER_MERCHANT_PatchPrivateProductCallback)( + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateProductResponse *result); + + +/** + * Start PATCH /private/products/$PRODUCT_ID operation. + * + * @param[in,out] pph operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductPatchHandle * -TALER_MERCHANT_product_patch2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - const char *description, - const json_t *description_i18n, - const char *unit, - const struct TALER_Amount *unit_prices, - size_t unit_price_len, - const char *image, - const json_t *taxes, - int64_t total_stock, - uint32_t total_stock_frac, - bool unit_allow_fraction, - const uint32_t *unit_precision_level, - uint64_t total_lost, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - TALER_MERCHANT_ProductPatchCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_product_start ( + struct TALER_MERCHANT_PatchPrivateProductHandle *pph, + TALER_MERCHANT_PatchPrivateProductCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/products/$PRODUCT_ID request. + * Cancel PATCH /private/products/$PRODUCT_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] pph handle to cancel + * @param[in] pph operation to cancel */ void -TALER_MERCHANT_product_patch_cancel ( - struct TALER_MERCHANT_ProductPatchHandle *pph); +TALER_MERCHANT_patch_private_product_cancel ( + struct TALER_MERCHANT_PatchPrivateProductHandle *pph); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_PRODUCTS_PRODUCT_ID_H */ diff --git a/src/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h b/src/include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h @@ -1,115 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h - * @brief C interface for PATCH /private/templates/$TEMPLATE_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a PATCH /private/templates/$TEMPLATE_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateTemplateHandle; - - -/** - * Set up PATCH /private/templates/$TEMPLATE_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param template_id identifier of the template to update - * @param template_description new human-readable description - * @param otp_id new OTP device ID, or NULL to remove association - * @param template_contract new template contract (JSON) - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_PatchPrivateTemplateHandle * -TALER_MERCHANT_patch_private_template_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id, - const char *template_description, - const char *otp_id, - json_t *template_contract); - - -/** - * Response details for a PATCH /private/templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_PatchPrivateTemplateResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateTemplateCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/templates/$TEMPLATE_ID request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateTemplateCallback)( - TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateTemplateResponse *result); - - -/** - * Start PATCH /private/templates/$TEMPLATE_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_template_start ( - struct TALER_MERCHANT_PatchPrivateTemplateHandle *handle, - TALER_MERCHANT_PatchPrivateTemplateCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/templates/$TEMPLATE_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_patch_private_template_cancel ( - struct TALER_MERCHANT_PatchPrivateTemplateHandle *handle); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_TEMPLATES_TEMPLATE_ID_NEW_H */ 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 @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h - * @brief C interface for PATCH /private/templates/$TEMPLATE_ID of the merchant backend + * @brief C interface for PATCH /private/templates/$TEMPLATE_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_TEMPLATES_TEMPLATE_ID_H @@ -26,56 +26,90 @@ /** - * Handle for a PATCH /private/templates/$TEMPLATE_ID request. + * Handle for a PATCH /private/templates/$TEMPLATE_ID operation. */ -struct TALER_MERCHANT_TemplatePatchHandle; +struct TALER_MERCHANT_PatchPrivateTemplateHandle; /** + * Set up PATCH /private/templates/$TEMPLATE_ID operation. + * Note that you must explicitly start the operation after setup. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param template_id identifier of the template to update + * @param template_description new human-readable description + * @param otp_id new OTP device ID, or NULL to remove association + * @param template_contract new template contract (JSON) + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_PatchPrivateTemplateHandle * +TALER_MERCHANT_patch_private_template_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *template_id, + const char *template_description, + const char *otp_id, + json_t *template_contract); + + +/** + * Response details for a PATCH /private/templates/$TEMPLATE_ID request. + */ +struct TALER_MERCHANT_PatchPrivateTemplateResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateTemplateCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE */ + +/** * Callback for a PATCH /private/templates/$TEMPLATE_ID request. * * @param cls closure - * @param hr HTTP response details + * @param result response details */ typedef void -(*TALER_MERCHANT_TemplatePatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_PatchPrivateTemplateCallback)( + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateTemplateResponse *result); /** - * Issue a PATCH /private/templates/$TEMPLATE_ID request to update a template. + * Start PATCH /private/templates/$TEMPLATE_ID operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param template_id identifier of the template to update - * @param template_description new human-readable description - * @param otp_id new OTP device ID, or NULL to remove association - * @param template_contract new template contract (JSON) - * @param cb callback to invoke with the result + * @param[in,out] handle operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_TemplatePatchHandle * -TALER_MERCHANT_template_patch ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - const char *template_description, - const char *otp_id, - json_t *template_contract, - TALER_MERCHANT_TemplatePatchCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_template_start ( + struct TALER_MERCHANT_PatchPrivateTemplateHandle *handle, + TALER_MERCHANT_PatchPrivateTemplateCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/templates/$TEMPLATE_ID request. + * Cancel PATCH /private/templates/$TEMPLATE_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] tph handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_template_patch_cancel ( - struct TALER_MERCHANT_TemplatePatchHandle *tph); +TALER_MERCHANT_patch_private_template_cancel ( + struct TALER_MERCHANT_PatchPrivateTemplateHandle *handle); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_TEMPLATES_TEMPLATE_ID_H */ diff --git a/src/include/taler/taler-merchant/patch-private-units-UNIT-new.h b/src/include/taler/taler-merchant/patch-private-units-UNIT-new.h @@ -1,376 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-units-UNIT-new.h - * @brief C interface for PATCH /private/units/$UNIT - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_UNITS_UNIT_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_UNITS_UNIT_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options we can set for the PATCH /private/units/$UNIT request. - */ -enum TALER_MERCHANT_PatchPrivateUnitOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_END = 0, - - /** - * Set the long name of the unit. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG, - - /** - * Set the short name (symbol) of the unit. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT, - - /** - * Set internationalized long names (JSON). - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N, - - /** - * Set internationalized short names (JSON). - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N, - - /** - * Set whether fractional quantities are allowed. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION, - - /** - * Set precision level for fractions. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL, - - /** - * Set active status of the unit. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE - -}; - - -/** - * Value for an option for the PATCH /private/units/$UNIT request. - */ -struct TALER_MERCHANT_PatchPrivateUnitOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PatchPrivateUnitOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG. - */ - const char *unit_name_long; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT. - */ - const char *unit_name_short; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N. - */ - const json_t *unit_name_long_i18n; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N. - */ - const json_t *unit_name_short_i18n; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION. - */ - bool unit_allow_fraction; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL. - */ - uint32_t unit_precision_level; - - /** - * Value if @e option is - * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE. - */ - bool unit_active; - - } details; - -}; - - -/** - * Handle for a PATCH /private/units/$UNIT operation. - */ -struct TALER_MERCHANT_PatchPrivateUnitHandle; - - -/** - * Set up PATCH /private/units/$UNIT operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param unit_id identifier of the unit to update - * @return handle to operation, NULL on error - */ -struct TALER_MERCHANT_PatchPrivateUnitHandle * -TALER_MERCHANT_patch_private_unit_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *unit_id); - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_end_() \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_END \ - } - -/** - * Set the long name of the unit. - * - * @param n long name to set - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_name_long(n) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG, \ - .details.unit_name_long = (n) \ - } - -/** - * Set the short name (symbol) of the unit. - * - * @param n short name to set - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_name_short(n) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT, \ - .details.unit_name_short = (n) \ - } - -/** - * Set internationalized long names. - * - * @param j JSON object with internationalized long names - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_name_long_i18n(j) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N \ - , \ - .details.unit_name_long_i18n = (j) \ - } - -/** - * Set internationalized short names. - * - * @param j JSON object with internationalized short names - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_name_short_i18n(j) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N, \ - .details.unit_name_short_i18n = (j) \ - } - -/** - * Set whether fractional quantities are allowed. - * - * @param a true if fractional quantities are allowed - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_allow_fraction(a) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION \ - , \ - .details.unit_allow_fraction = (a) \ - } - -/** - * Set precision level for fractions. - * - * @param p precision level value - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_precision_level(p) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL, \ - .details.unit_precision_level = (p) \ - } - -/** - * Set active status of the unit. - * - * @param a true if the unit should be active - * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue - */ -#define TALER_MERCHANT_patch_private_unit_option_unit_active(a) \ - (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ - { \ - .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE, \ - .details.unit_active = (a) \ - } - - -/** - * Set the requested options for the operation. - * - * If any option fail other options may be or may be not applied. - * - * @param uph 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_unit_set_options_ ( - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, - unsigned int num_options, - const struct TALER_MERCHANT_PatchPrivateUnitOptionValue *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_unit_set_options ( - * uph, - * TALER_MERCHANT_patch_private_unit_option_unit_name_long ("Kilogram"), - * TALER_MERCHANT_patch_private_unit_option_unit_active (true)); - * - * @param uph the request to set the options for - * @param ... the list of the options, each option must be created - * by helpers TALER_MERCHANT_patch_private_unit_option_NAME(VALUE) - * @return #GNUNET_OK on success, - * #GNUNET_NO on failure, - * #GNUNET_SYSERR on internal error - */ -#define TALER_MERCHANT_patch_private_unit_set_options(uph,...) \ - TALER_MERCHANT_patch_private_unit_set_options_ ( \ - uph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PatchPrivateUnitOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_patch_private_unit_option_end_ () } \ - )) - - -/** - * Response details for a PATCH /private/units/$UNIT request. - */ -struct TALER_MERCHANT_PatchPrivateUnitResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateUnitCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/units/$UNIT request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateUnitCallback)( - TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateUnitResponse *result); - - -/** - * Start PATCH /private/units/$UNIT operation. - * - * @param[in,out] uph operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_unit_start ( - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, - TALER_MERCHANT_PatchPrivateUnitCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/units/$UNIT operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] uph operation to cancel - */ -void -TALER_MERCHANT_patch_private_unit_cancel ( - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_UNITS_UNIT_NEW_H */ diff --git a/src/include/taler/taler-merchant/patch-private-units-UNIT.h b/src/include/taler/taler-merchant/patch-private-units-UNIT.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-units-UNIT.h - * @brief C interface for PATCH /private/units/$UNIT of the merchant backend + * @brief C interface for PATCH /private/units/$UNIT * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_UNITS_UNIT_H @@ -26,64 +26,351 @@ /** - * Handle for a PATCH /private/units/$UNIT request. + * Possible options we can set for the PATCH /private/units/$UNIT request. */ -struct TALER_MERCHANT_UnitPatchHandle; +enum TALER_MERCHANT_PatchPrivateUnitOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_END = 0, + /** + * Set the long name of the unit. + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG, + + /** + * Set the short name (symbol) of the unit. + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT, + + /** + * Set internationalized long names (JSON). + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N, + + /** + * Set internationalized short names (JSON). + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N, + + /** + * Set whether fractional quantities are allowed. + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION, + + /** + * Set precision level for fractions. + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL, + + /** + * Set active status of the unit. + */ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE + +}; + + +/** + * Value for an option for the PATCH /private/units/$UNIT request. + */ +struct TALER_MERCHANT_PatchPrivateUnitOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PatchPrivateUnitOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG. + */ + const char *unit_name_long; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT. + */ + const char *unit_name_short; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N. + */ + const json_t *unit_name_long_i18n; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N. + */ + const json_t *unit_name_short_i18n; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION. + */ + bool unit_allow_fraction; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL. + */ + uint32_t unit_precision_level; + + /** + * Value if @e option is + * #TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE. + */ + bool unit_active; + + } details; + +}; + + +/** + * Handle for a PATCH /private/units/$UNIT operation. + */ +struct TALER_MERCHANT_PatchPrivateUnitHandle; + + +/** + * Set up PATCH /private/units/$UNIT operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param unit_id identifier of the unit to update + * @return handle to operation, NULL on error + */ +struct TALER_MERCHANT_PatchPrivateUnitHandle * +TALER_MERCHANT_patch_private_unit_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *unit_id); + + +/** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_end_() \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_END \ + } + +/** + * Set the long name of the unit. + * + * @param n long name to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_name_long(n) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG, \ + .details.unit_name_long = (n) \ + } + +/** + * Set the short name (symbol) of the unit. + * + * @param n short name to set + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_name_short(n) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT, \ + .details.unit_name_short = (n) \ + } + +/** + * Set internationalized long names. + * + * @param j JSON object with internationalized long names + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_name_long_i18n(j) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N \ + , \ + .details.unit_name_long_i18n = (j) \ + } + +/** + * Set internationalized short names. + * + * @param j JSON object with internationalized short names + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_name_short_i18n(j) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N, \ + .details.unit_name_short_i18n = (j) \ + } + +/** + * Set whether fractional quantities are allowed. + * + * @param a true if fractional quantities are allowed + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_allow_fraction(a) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION \ + , \ + .details.unit_allow_fraction = (a) \ + } + +/** + * Set precision level for fractions. + * + * @param p precision level value + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_precision_level(p) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL, \ + .details.unit_precision_level = (p) \ + } + +/** + * Set active status of the unit. + * + * @param a true if the unit should be active + * @return representation of the option as a struct TALER_MERCHANT_PatchPrivateUnitOptionValue + */ +#define TALER_MERCHANT_patch_private_unit_option_unit_active(a) \ + (const struct TALER_MERCHANT_PatchPrivateUnitOptionValue) \ + { \ + .option = TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE, \ + .details.unit_active = (a) \ + } + + +/** + * Set the requested options for the operation. + * + * If any option fail other options may be or may be not applied. + * + * @param uph 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_unit_set_options_ ( + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateUnitOptionValue *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_unit_set_options ( + * uph, + * TALER_MERCHANT_patch_private_unit_option_unit_name_long ("Kilogram"), + * TALER_MERCHANT_patch_private_unit_option_unit_active (true)); + * + * @param uph the request to set the options for + * @param ... the list of the options, each option must be created + * by helpers TALER_MERCHANT_patch_private_unit_option_NAME(VALUE) + * @return #GNUNET_OK on success, + * #GNUNET_NO on failure, + * #GNUNET_SYSERR on internal error + */ +#define TALER_MERCHANT_patch_private_unit_set_options(uph,...) \ + TALER_MERCHANT_patch_private_unit_set_options_ ( \ + uph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PatchPrivateUnitOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_patch_private_unit_option_end_ () } \ + )) + + +/** + * Response details for a PATCH /private/units/$UNIT request. + */ +struct TALER_MERCHANT_PatchPrivateUnitResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateUnitCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE */ /** * Callback for a PATCH /private/units/$UNIT request. * * @param cls closure - * @param hr HTTP response details + * @param result response details */ typedef void -(*TALER_MERCHANT_UnitPatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_PatchPrivateUnitCallback)( + TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateUnitResponse *result); /** - * Issue a PATCH /private/units/$UNIT request to update a unit. + * Start PATCH /private/units/$UNIT operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param unit_id identifier of the unit to update - * @param unit_name_long new long name, or NULL to keep unchanged - * @param unit_name_short new short symbol, or NULL to keep unchanged - * @param unit_name_long_i18n new internationalized long names (JSON), or NULL - * @param unit_name_short_i18n new internationalized short names (JSON), or NULL - * @param unit_allow_fraction new value for allow_fraction, or NULL to keep unchanged - * @param unit_precision_level new precision level, or NULL to keep unchanged - * @param unit_active new active status, or NULL to keep unchanged - * @param cb callback to invoke with the result + * @param[in,out] uph operation to start + * @param cb function to call with the result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_UnitPatchHandle * -TALER_MERCHANT_unit_patch ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *unit_id, - const char *unit_name_long, - const char *unit_name_short, - const json_t *unit_name_long_i18n, - const json_t *unit_name_short_i18n, - const bool *unit_allow_fraction, - const uint32_t *unit_precision_level, - const bool *unit_active, - TALER_MERCHANT_UnitPatchCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_unit_start ( + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, + TALER_MERCHANT_PatchPrivateUnitCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/units/$UNIT request. + * Cancel PATCH /private/units/$UNIT operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] uph handle to cancel + * @param[in] uph operation to cancel */ void -TALER_MERCHANT_unit_patch_cancel ( - struct TALER_MERCHANT_UnitPatchHandle *uph); +TALER_MERCHANT_patch_private_unit_cancel ( + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_UNITS_UNIT_H */ diff --git a/src/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h b/src/include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h @@ -1,119 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h - * @brief C interface for PATCH /private/webhooks/$WEBHOOK_ID - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__PATCH_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H -#define _TALER_MERCHANT__PATCH_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a PATCH /private/webhooks/$WEBHOOK_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateWebhookHandle; - - -/** - * Set up PATCH /private/webhooks/$WEBHOOK_ID operation. - * Note that you must explicitly start the operation after setup. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param webhook_id identifier of the webhook to update - * @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 * -TALER_MERCHANT_patch_private_webhook_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id, - const char *event_type, - const char *url_template, - const char *http_method, - const char *header_template, - const char *body_template); - - -/** - * Response details for a PATCH /private/webhooks/$WEBHOOK_ID request. - */ -struct TALER_MERCHANT_PatchPrivateWebhookResponse -{ - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; -}; - - -#ifndef TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PatchPrivateWebhookCallback. - */ -#define TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE */ - -/** - * Callback for a PATCH /private/webhooks/$WEBHOOK_ID request. - * - * @param cls closure - * @param result response details - */ -typedef void -(*TALER_MERCHANT_PatchPrivateWebhookCallback)( - TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PatchPrivateWebhookResponse *result); - - -/** - * Start PATCH /private/webhooks/$WEBHOOK_ID operation. - * - * @param[in,out] handle operation to start - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_webhook_start ( - struct TALER_MERCHANT_PatchPrivateWebhookHandle *handle, - TALER_MERCHANT_PatchPrivateWebhookCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel PATCH /private/webhooks/$WEBHOOK_ID operation. - * This function must not be called by clients after the - * callback has been invoked. - * - * @param[in] handle operation to cancel - */ -void -TALER_MERCHANT_patch_private_webhook_cancel ( - struct TALER_MERCHANT_PatchPrivateWebhookHandle *handle); - - -#endif /* _TALER_MERCHANT__PATCH_PRIVATE_WEBHOOKS_WEBHOOK_ID_NEW_H */ 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 @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h - * @brief C interface for PATCH /private/webhooks/$WEBHOOK_ID of the merchant backend + * @brief C interface for PATCH /private/webhooks/$WEBHOOK_ID * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__PATCH_PRIVATE_WEBHOOKS_WEBHOOK_ID_H @@ -26,60 +26,94 @@ /** - * Handle for a PATCH /private/webhooks/$WEBHOOK_ID request. + * Handle for a PATCH /private/webhooks/$WEBHOOK_ID operation. */ -struct TALER_MERCHANT_WebhookPatchHandle; +struct TALER_MERCHANT_PatchPrivateWebhookHandle; /** - * Callback for a PATCH /private/webhooks/$WEBHOOK_ID request. - * - * @param cls closure - * @param hr HTTP response details - */ -typedef void -(*TALER_MERCHANT_WebhookPatchCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); - - -/** - * Issue a PATCH /private/webhooks/$WEBHOOK_ID request to update a webhook. + * Set up PATCH /private/webhooks/$WEBHOOK_ID operation. + * Note that you must explicitly start the operation after setup. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param webhook_id identifier of the webhook to update * @param event_type new event type - * @param url new notification URL + * @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 - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation, NULL on error */ -struct TALER_MERCHANT_WebhookPatchHandle * -TALER_MERCHANT_webhook_patch ( +struct TALER_MERCHANT_PatchPrivateWebhookHandle * +TALER_MERCHANT_patch_private_webhook_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *webhook_id, const char *event_type, - const char *url, + const char *url_template, const char *http_method, const char *header_template, - const char *body_template, - TALER_MERCHANT_WebhookPatchCallback cb, - void *cb_cls); + const char *body_template); + + +/** + * Response details for a PATCH /private/webhooks/$WEBHOOK_ID request. + */ +struct TALER_MERCHANT_PatchPrivateWebhookResponse +{ + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; +}; + + +#ifndef TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PatchPrivateWebhookCallback. + */ +#define TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE */ + +/** + * Callback for a PATCH /private/webhooks/$WEBHOOK_ID request. + * + * @param cls closure + * @param result response details + */ +typedef void +(*TALER_MERCHANT_PatchPrivateWebhookCallback)( + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PatchPrivateWebhookResponse *result); + + +/** + * Start PATCH /private/webhooks/$WEBHOOK_ID operation. + * + * @param[in,out] handle operation to start + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_webhook_start ( + struct TALER_MERCHANT_PatchPrivateWebhookHandle *handle, + TALER_MERCHANT_PatchPrivateWebhookCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls); /** - * Cancel a PATCH /private/webhooks/$WEBHOOK_ID request. + * Cancel PATCH /private/webhooks/$WEBHOOK_ID operation. + * This function must not be called by clients after the + * callback has been invoked. * - * @param[in] wph handle to cancel + * @param[in] handle operation to cancel */ void -TALER_MERCHANT_webhook_patch_cancel ( - struct TALER_MERCHANT_WebhookPatchHandle *wph); +TALER_MERCHANT_patch_private_webhook_cancel ( + struct TALER_MERCHANT_PatchPrivateWebhookHandle *handle); -#endif +#endif /* _TALER_MERCHANT__PATCH_PRIVATE_WEBHOOKS_WEBHOOK_ID_H */ diff --git a/src/include/taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h b/src/include/taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h @@ -1,115 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h - * @brief C interface for the POST /management/instances/$INSTANCE/auth endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_INSTANCE_AUTH_NEW_H -#define _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_INSTANCE_AUTH_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /management/instances/$INSTANCE/auth request. - */ -struct TALER_MERCHANT_PostManagementInstancesAuthHandle; - - -/** - * Response details for a POST /management/instances/$INSTANCE/auth request. - */ -struct TALER_MERCHANT_PostManagementInstancesAuthResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Set up POST /management/instances/$INSTANCE/auth operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param instance_id identifier of the instance - * @param auth_password new authentication password - * @return handle to operation - */ -struct TALER_MERCHANT_PostManagementInstancesAuthHandle * -TALER_MERCHANT_post_management_instances_auth_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - const char *auth_password); // FIXME: make password an option! - - -#ifndef TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostManagementInstancesAuthCallback. - */ -#define TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE */ - -/** - * Callback for a POST /management/instances/$INSTANCE/auth request. - * - * @param cls closure - * @param iar response details - */ -typedef void -(*TALER_MERCHANT_PostManagementInstancesAuthCallback)( - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostManagementInstancesAuthResponse *iar); - - -/** - * Start POST /management/instances/$INSTANCE/auth operation. - * - * @param[in,out] piah operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_management_instances_auth_start ( - struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah, - TALER_MERCHANT_PostManagementInstancesAuthCallback cb, - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /management/instances/$INSTANCE/auth operation. This function - * must not be called by clients after the - * TALER_MERCHANT_PostManagementInstancesAuthCallback has been invoked (as in - * those cases it'll be called internally by the implementation already). - * - * @param[in] piah operation to cancel - */ -void -TALER_MERCHANT_post_management_instances_auth_cancel ( - struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah); - - -#endif /* _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_INSTANCE_AUTH_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-management-instances-INSTANCE-auth.h b/src/include/taler/taler-merchant/post-management-instances-INSTANCE-auth.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-management-instances-INSTANCE-auth.h - * @brief C interface for POST /management/instances/$INSTANCE/auth of the merchant backend + * @brief C interface for the POST /management/instances/$INSTANCE/auth endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_INSTANCE_AUTH_H @@ -28,51 +28,88 @@ /** * Handle for a POST /management/instances/$INSTANCE/auth request. */ -struct TALER_MERCHANT_InstanceAuthPostHandle; +struct TALER_MERCHANT_PostManagementInstancesAuthHandle; /** + * Response details for a POST /management/instances/$INSTANCE/auth request. + */ +struct TALER_MERCHANT_PostManagementInstancesAuthResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Set up POST /management/instances/$INSTANCE/auth operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param instance_id identifier of the instance + * @param auth_password new authentication password + * @return handle to operation + */ +struct TALER_MERCHANT_PostManagementInstancesAuthHandle * +TALER_MERCHANT_post_management_instances_auth_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id, + const char *auth_password); // FIXME: make password an option! + + +#ifndef TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostManagementInstancesAuthCallback. + */ +#define TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE */ + +/** * Callback for a POST /management/instances/$INSTANCE/auth request. * * @param cls closure - * @param hr HTTP response details + * @param iar response details */ typedef void -(*TALER_MERCHANT_InstanceAuthPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_PostManagementInstancesAuthCallback)( + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostManagementInstancesAuthResponse *iar); /** - * Issue a POST /management/instances/$INSTANCE/auth request to update - * authentication credentials for an instance. + * Start POST /management/instances/$INSTANCE/auth operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param instance_id identifier of the instance - * @param auth_password new authentication password - * @param cb callback to invoke with the result + * @param[in,out] piah operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_InstanceAuthPostHandle * -TALER_MERCHANT_instance_auth_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - const char *auth_password, - TALER_MERCHANT_InstanceAuthPostCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_management_instances_auth_start ( + struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah, + TALER_MERCHANT_PostManagementInstancesAuthCallback cb, + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /management/instances/$INSTANCE/auth request. + * Cancel POST /management/instances/$INSTANCE/auth operation. This function + * must not be called by clients after the + * TALER_MERCHANT_PostManagementInstancesAuthCallback has been invoked (as in + * those cases it'll be called internally by the implementation already). * - * @param[in] iaph handle to cancel + * @param[in] piah operation to cancel */ void -TALER_MERCHANT_instance_auth_post_cancel ( - struct TALER_MERCHANT_InstanceAuthPostHandle *iaph); +TALER_MERCHANT_post_management_instances_auth_cancel ( + struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah); -#endif +#endif /* _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_INSTANCE_AUTH_H */ diff --git a/src/include/taler/taler-merchant/post-management-instances-new.h b/src/include/taler/taler-merchant/post-management-instances-new.h @@ -1,129 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-management-instances-new.h - * @brief C interface for the POST /management/instances endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_NEW_H -#define _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /management/instances request. - */ -struct TALER_MERCHANT_PostManagementInstancesHandle; - - -/** - * Response details for a POST /management/instances request. - */ -struct TALER_MERCHANT_PostManagementInstancesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Set up POST /management/instances operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param instance_id identifier for the new instance - * @param name human-readable name - * @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 * -TALER_MERCHANT_post_management_instances_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - 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); - - -#ifndef TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostManagementInstancesCallback. - */ -#define TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE */ - -/** - * Callback for a POST /management/instances request. - * - * @param cls closure - * @param mir response details - */ -typedef void -(*TALER_MERCHANT_PostManagementInstancesCallback)( - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostManagementInstancesResponse *mir); - - -/** - * Start POST /management/instances operation. - * - * @param[in,out] pmih operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_management_instances_start ( - struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, - TALER_MERCHANT_PostManagementInstancesCallback cb, - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /management/instances operation. This function must not be - * called by clients after the TALER_MERCHANT_PostManagementInstancesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] pmih operation to cancel - */ -void -TALER_MERCHANT_post_management_instances_cancel ( - struct TALER_MERCHANT_PostManagementInstancesHandle *pmih); - - -#endif /* _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-management-instances.h b/src/include/taler/taler-merchant/post-management-instances.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-management-instances.h - * @brief C interface for POST /management/instances of the merchant backend + * @brief C interface for the POST /management/instances endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_H @@ -28,26 +28,30 @@ /** * Handle for a POST /management/instances request. */ -struct TALER_MERCHANT_InstancesPostHandle; +struct TALER_MERCHANT_PostManagementInstancesHandle; /** - * Callback for a POST /management/instances request. - * - * @param cls closure - * @param hr HTTP response details + * Response details for a POST /management/instances request. */ -typedef void -(*TALER_MERCHANT_InstancesPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +struct TALER_MERCHANT_PostManagementInstancesResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; /** - * Issue a POST /management/instances request to create a new instance. + * Set up POST /management/instances operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param instance_id identifier for the new instance * @param name human-readable name * @param address address (JSON) @@ -57,14 +61,12 @@ typedef void * @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 - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_InstancesPostHandle * -TALER_MERCHANT_instances_post ( +struct TALER_MERCHANT_PostManagementInstancesHandle * +TALER_MERCHANT_post_management_instances_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, const char *name, const json_t *address, @@ -73,19 +75,55 @@ TALER_MERCHANT_instances_post ( 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, - TALER_MERCHANT_InstancesPostCallback cb, - void *cb_cls); + const char *auth_password); + + +#ifndef TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostManagementInstancesCallback. + */ +#define TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE */ + +/** + * Callback for a POST /management/instances request. + * + * @param cls closure + * @param mir response details + */ +typedef void +(*TALER_MERCHANT_PostManagementInstancesCallback)( + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostManagementInstancesResponse *mir); + + +/** + * Start POST /management/instances operation. + * + * @param[in,out] pmih operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_management_instances_start ( + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, + TALER_MERCHANT_PostManagementInstancesCallback cb, + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /management/instances request. + * Cancel POST /management/instances operation. This function must not be + * called by clients after the TALER_MERCHANT_PostManagementInstancesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] iph handle to cancel + * @param[in] pmih operation to cancel */ void -TALER_MERCHANT_instances_post_cancel ( - struct TALER_MERCHANT_InstancesPostHandle *iph); +TALER_MERCHANT_post_management_instances_cancel ( + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih); -#endif +#endif /* _TALER_MERCHANT__POST_MANAGEMENT_INSTANCES_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-abort-new.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-abort-new.h @@ -1,210 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-orders-ORDER_ID-abort-new.h - * @brief C interface for the POST /orders/$ORDER_ID/abort endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_ABORT_NEW_H -#define _TALER_MERCHANT__POST_ORDERS_ORDER_ID_ABORT_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /orders/$ORDER_ID/abort request. - */ -struct TALER_MERCHANT_PostOrdersAbortHandle; - - -/** - * One coin used in an abort request. - */ -struct TALER_MERCHANT_PostOrdersAbortCoin -{ - - /** - * Base URL of the exchange this coin was issued by. - */ - const char *exchange_url; - - /** - * Public key of the coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Total amount contributed including deposit fee. - */ - struct TALER_Amount amount_with_fee; - - /** - * Hash of the denomination public key. - */ - struct TALER_DenominationHashP denom_pub_hash; - - /** - * Denomination signature over the coin. - */ - struct TALER_DenominationSignature denom_sig; - - /** - * Amount contributed without the deposit fee. - */ - struct TALER_Amount contribution; - -}; - - -/** - * Result for one coin from an abort operation. - */ -struct TALER_MERCHANT_PostOrdersAbortedCoin -{ - - /** - * Exchange signature confirming the refund. - */ - struct TALER_ExchangeSignatureP exchange_sig; - - /** - * Exchange public key used for @e exchange_sig. - */ - struct TALER_ExchangePublicKeyP exchange_pub; - - /** - * Public key of the coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - -}; - - -/** - * Response details for a POST /orders/$ORDER_ID/abort request. - */ -struct TALER_MERCHANT_PostOrdersAbortResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of aborted coins in @a aborts. - */ - unsigned int num_aborts; - - /** - * Array of aborted coin results. - */ - const struct TALER_MERCHANT_PostOrdersAbortedCoin *aborts; - - } ok; - - } details; - -}; - - -/** - * Set up POST /orders/$ORDER_ID/abort operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to abort - * @param merchant_pub merchant public key - * @param h_contract hash of the contract terms - * @param num_coins number of coins in @a coins - * @param coins array of coins used in the aborted payment - * @return handle to operation - */ -struct TALER_MERCHANT_PostOrdersAbortHandle * -TALER_MERCHANT_post_orders_abort_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_PrivateContractHashP *h_contract, - unsigned int num_coins, - const struct TALER_MERCHANT_PostOrdersAbortCoin coins[static num_coins]); - - -#ifndef TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostOrdersAbortCallback. - */ -#define TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE */ - -/** - * Callback for a POST /orders/$ORDER_ID/abort request. - * - * @param cls closure - * @param oar response details - */ -typedef void -(*TALER_MERCHANT_PostOrdersAbortCallback)( - TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostOrdersAbortResponse *oar); - - -/** - * Start POST /orders/$ORDER_ID/abort operation. - * - * @param[in,out] poah operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_abort_start ( - struct TALER_MERCHANT_PostOrdersAbortHandle *poah, - TALER_MERCHANT_PostOrdersAbortCallback cb, - TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /orders/$ORDER_ID/abort operation. This function must not be - * called by clients after the TALER_MERCHANT_PostOrdersAbortCallback has - * been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] poah operation to cancel - */ -void -TALER_MERCHANT_post_orders_abort_cancel ( - struct TALER_MERCHANT_PostOrdersAbortHandle *poah); - - -#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_ABORT_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-abort.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-abort.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-orders-ORDER_ID-abort.h - * @brief C interface for POST /orders/$ORDER_ID/abort of the merchant backend + * @brief C interface for the POST /orders/$ORDER_ID/abort endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_ABORT_H @@ -28,53 +28,68 @@ /** * Handle for a POST /orders/$ORDER_ID/abort request. */ -struct TALER_MERCHANT_OrderAbortHandle; +struct TALER_MERCHANT_PostOrdersAbortHandle; /** - * Coin sent with an abort request. + * One coin used in an abort request. */ -struct TALER_MERCHANT_AbortCoin +struct TALER_MERCHANT_PostOrdersAbortCoin { /** + * Base URL of the exchange this coin was issued by. + */ + const char *exchange_url; + + /** * Public key of the coin. */ struct TALER_CoinSpendPublicKeyP coin_pub; /** - * Amount contributed by this coin including deposit fee. + * Total amount contributed including deposit fee. */ struct TALER_Amount amount_with_fee; /** - * Hash of the coin's denomination public key. + * Hash of the denomination public key. */ - struct TALER_DenominationHashP h_denom; + struct TALER_DenominationHashP denom_pub_hash; /** - * Base URL of the exchange this coin was issued by. + * Denomination signature over the coin. */ - const char *exchange_url; + struct TALER_DenominationSignature denom_sig; + + /** + * Amount contributed without the deposit fee. + */ + struct TALER_Amount contribution; }; /** - * Result for one coin in an abort response. + * Result for one coin from an abort operation. */ -struct TALER_MERCHANT_AbortedCoin +struct TALER_MERCHANT_PostOrdersAbortedCoin { /** - * Exchange public key used for the refund. + * Exchange signature confirming the refund. + */ + struct TALER_ExchangeSignatureP exchange_sig; + + /** + * Exchange public key used for @e exchange_sig. */ struct TALER_ExchangePublicKeyP exchange_pub; /** - * Exchange signature over the refund. + * Public key of the coin. */ - struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_CoinSpendPublicKeyP coin_pub; }; @@ -82,7 +97,7 @@ struct TALER_MERCHANT_AbortedCoin /** * Response details for a POST /orders/$ORDER_ID/abort request. */ -struct TALER_MERCHANT_AbortResponse +struct TALER_MERCHANT_PostOrdersAbortResponse { /** @@ -103,19 +118,14 @@ struct TALER_MERCHANT_AbortResponse { /** - * Public key of the merchant. - */ - const struct TALER_MerchantPublicKeyP *merchant_pub; - - /** * Number of aborted coins in @a aborts. */ unsigned int num_aborts; /** - * Array of per-coin abort results. + * Array of aborted coin results. */ - const struct TALER_MERCHANT_AbortedCoin *aborts; + const struct TALER_MERCHANT_PostOrdersAbortedCoin *aborts; } ok; @@ -125,53 +135,76 @@ struct TALER_MERCHANT_AbortResponse /** + * Set up POST /orders/$ORDER_ID/abort operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order to abort + * @param merchant_pub merchant public key + * @param h_contract hash of the contract terms + * @param num_coins number of coins in @a coins + * @param coins array of coins used in the aborted payment + * @return handle to operation + */ +struct TALER_MERCHANT_PostOrdersAbortHandle * +TALER_MERCHANT_post_orders_abort_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_PrivateContractHashP *h_contract, + unsigned int num_coins, + const struct TALER_MERCHANT_PostOrdersAbortCoin coins[static num_coins]); + + +#ifndef TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostOrdersAbortCallback. + */ +#define TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE */ + +/** * Callback for a POST /orders/$ORDER_ID/abort request. * * @param cls closure - * @param ar response details + * @param oar response details */ typedef void -(*TALER_MERCHANT_AbortCallback)( - void *cls, - const struct TALER_MERCHANT_AbortResponse *ar); +(*TALER_MERCHANT_PostOrdersAbortCallback)( + TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostOrdersAbortResponse *oar); /** - * Issue a POST /orders/$ORDER_ID/abort request to abort a payment - * and obtain refund signatures for the coins used. + * Start POST /orders/$ORDER_ID/abort operation. * - * @param ctx CURL context to use - * @param merchant_url base URL of the merchant backend - * @param order_id identifier of the order to abort - * @param merchant_pub public key of the merchant instance - * @param h_contract hash of the contract terms - * @param num_coins number of coins in @a coins - * @param coins array of coins that were used for payment - * @param cb callback to invoke with the result + * @param[in,out] poah operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderAbortHandle * -TALER_MERCHANT_order_abort ( - struct GNUNET_CURL_Context *ctx, - const char *merchant_url, - const char *order_id, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_PrivateContractHashP *h_contract, - unsigned int num_coins, - const struct TALER_MERCHANT_AbortCoin coins[static num_coins], - TALER_MERCHANT_AbortCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_abort_start ( + struct TALER_MERCHANT_PostOrdersAbortHandle *poah, + TALER_MERCHANT_PostOrdersAbortCallback cb, + TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /orders/$ORDER_ID/abort request. + * Cancel POST /orders/$ORDER_ID/abort operation. This function must not be + * called by clients after the TALER_MERCHANT_PostOrdersAbortCallback has + * been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] oah handle to cancel + * @param[in] poah operation to cancel */ void -TALER_MERCHANT_order_abort_cancel ( - struct TALER_MERCHANT_OrderAbortHandle *oah); +TALER_MERCHANT_post_orders_abort_cancel ( + struct TALER_MERCHANT_PostOrdersAbortHandle *poah); -#endif +#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_ABORT_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-claim-new.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-claim-new.h @@ -1,252 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-orders-ORDER_ID-claim-new.h - * @brief C interface for the POST /orders/$ORDER_ID/claim endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_CLAIM_NEW_H -#define _TALER_MERCHANT__POST_ORDERS_ORDER_ID_CLAIM_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /orders/$ORDER_ID/claim request. - */ -enum TALER_MERCHANT_PostOrdersClaimOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_END = 0, - - /** - * Claim token for the order. - */ - TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN - -}; - - -/** - * Value for an option for the POST /orders/$ORDER_ID/claim request. - */ -struct TALER_MERCHANT_PostOrdersClaimOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostOrdersClaimOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN. - */ - const struct TALER_ClaimTokenP *token; - - } details; - -}; - - -/** - * Handle for a POST /orders/$ORDER_ID/claim request. - */ -struct TALER_MERCHANT_PostOrdersClaimHandle; - - -/** - * Response details for a POST /orders/$ORDER_ID/claim request. - */ -struct TALER_MERCHANT_PostOrdersClaimResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * The claimed contract terms. - */ - const json_t *contract_terms; - - /** - * Hash of the contract terms. - */ - struct TALER_PrivateContractHashP h_contract_terms; - - /** - * Merchant signature over the contract terms. - */ - struct TALER_MerchantSignatureP merchant_sig; - - } ok; - - } details; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PostOrdersClaimOptionValue - */ -#define TALER_MERCHANT_post_orders_claim_option_end_() \ - (const struct TALER_MERCHANT_PostOrdersClaimOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_END \ - } - -/** - * Set claim token. - * - * @param t claim token to use - * @return representation of the option as a struct TALER_MERCHANT_PostOrdersClaimOptionValue - */ -#define TALER_MERCHANT_post_orders_claim_option_token(t) \ - (const struct TALER_MERCHANT_PostOrdersClaimOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN, \ - .details.token = (t) \ - } - - -/** - * Set the requested options for the operation. - * - * @param poch 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_orders_claim_set_options_ ( - struct TALER_MERCHANT_PostOrdersClaimHandle *poch, - unsigned int num_options, - const struct TALER_MERCHANT_PostOrdersClaimOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param poch 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_orders_claim_set_options(poch,...) \ - TALER_MERCHANT_post_orders_claim_set_options_ ( \ - poch, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostOrdersClaimOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_orders_claim_option_end_ () } \ - )) - - -/** - * Set up POST /orders/$ORDER_ID/claim operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to claim - * @param nonce wallet nonce for claiming - * @return handle to operation - */ -struct TALER_MERCHANT_PostOrdersClaimHandle * -TALER_MERCHANT_post_orders_claim_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct GNUNET_CRYPTO_EddsaPublicKey *nonce); - - -#ifndef TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostOrdersClaimCallback. - */ -#define TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE */ - -/** - * Callback for a POST /orders/$ORDER_ID/claim request. - * - * @param cls closure - * @param ocr response details - */ -typedef void -(*TALER_MERCHANT_PostOrdersClaimCallback)( - TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostOrdersClaimResponse *ocr); - - -/** - * Start POST /orders/$ORDER_ID/claim operation. - * - * @param[in,out] poch operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_claim_start ( - struct TALER_MERCHANT_PostOrdersClaimHandle *poch, - TALER_MERCHANT_PostOrdersClaimCallback cb, - TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /orders/$ORDER_ID/claim operation. This function must not be - * called by clients after the TALER_MERCHANT_PostOrdersClaimCallback has - * been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] poch operation to cancel - */ -void -TALER_MERCHANT_post_orders_claim_cancel ( - struct TALER_MERCHANT_PostOrdersClaimHandle *poch); - - -#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_CLAIM_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-claim.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-claim.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-orders-ORDER_ID-claim.h - * @brief C interface for POST /orders/$ORDER_ID/claim of the merchant backend + * @brief C interface for the POST /orders/$ORDER_ID/claim endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_CLAIM_H @@ -26,15 +26,61 @@ /** + * Possible options for the POST /orders/$ORDER_ID/claim request. + */ +enum TALER_MERCHANT_PostOrdersClaimOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_END = 0, + + /** + * Claim token for the order. + */ + TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN + +}; + + +/** + * Value for an option for the POST /orders/$ORDER_ID/claim request. + */ +struct TALER_MERCHANT_PostOrdersClaimOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostOrdersClaimOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN. + */ + const struct TALER_ClaimTokenP *token; + + } details; + +}; + + +/** * Handle for a POST /orders/$ORDER_ID/claim request. */ -struct TALER_MERCHANT_OrderClaimHandle; +struct TALER_MERCHANT_PostOrdersClaimHandle; /** * Response details for a POST /orders/$ORDER_ID/claim request. */ -struct TALER_MERCHANT_OrderClaimResponse +struct TALER_MERCHANT_PostOrdersClaimResponse { /** @@ -55,19 +101,19 @@ struct TALER_MERCHANT_OrderClaimResponse { /** - * Contract terms (JSON). + * The claimed contract terms. */ const json_t *contract_terms; /** - * Merchant signature over the contract terms. + * Hash of the contract terms. */ - struct TALER_MerchantSignatureP sig; + struct TALER_PrivateContractHashP h_contract_terms; /** - * Hash of the contract terms. + * Merchant signature over the contract terms. */ - struct TALER_PrivateContractHashP h_contract_terms; + struct TALER_MerchantSignatureP merchant_sig; } ok; @@ -77,49 +123,130 @@ struct TALER_MERCHANT_OrderClaimResponse /** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PostOrdersClaimOptionValue + */ +#define TALER_MERCHANT_post_orders_claim_option_end_() \ + (const struct TALER_MERCHANT_PostOrdersClaimOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_END \ + } + +/** + * Set claim token. + * + * @param t claim token to use + * @return representation of the option as a struct TALER_MERCHANT_PostOrdersClaimOptionValue + */ +#define TALER_MERCHANT_post_orders_claim_option_token(t) \ + (const struct TALER_MERCHANT_PostOrdersClaimOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN, \ + .details.token = (t) \ + } + + +/** + * Set the requested options for the operation. + * + * @param poch 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_orders_claim_set_options_ ( + struct TALER_MERCHANT_PostOrdersClaimHandle *poch, + unsigned int num_options, + const struct TALER_MERCHANT_PostOrdersClaimOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param poch 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_orders_claim_set_options(poch,...) \ + TALER_MERCHANT_post_orders_claim_set_options_ ( \ + poch, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostOrdersClaimOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_orders_claim_option_end_ () } \ + )) + + +/** + * Set up POST /orders/$ORDER_ID/claim operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order to claim + * @param nonce wallet nonce for claiming + * @return handle to operation + */ +struct TALER_MERCHANT_PostOrdersClaimHandle * +TALER_MERCHANT_post_orders_claim_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct GNUNET_CRYPTO_EddsaPublicKey *nonce); + + +#ifndef TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostOrdersClaimCallback. + */ +#define TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE */ + +/** * Callback for a POST /orders/$ORDER_ID/claim request. * * @param cls closure * @param ocr response details */ typedef void -(*TALER_MERCHANT_OrderClaimCallback)( - void *cls, - const struct TALER_MERCHANT_OrderClaimResponse *ocr); +(*TALER_MERCHANT_PostOrdersClaimCallback)( + TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostOrdersClaimResponse *ocr); /** - * Issue a POST /orders/$ORDER_ID/claim request to claim an order - * and obtain its contract terms. + * Start POST /orders/$ORDER_ID/claim operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order_id identifier of the order to claim - * @param nonce wallet nonce for the claim - * @param claim_token claim token (if required), or NULL - * @param cb callback to invoke with the result + * @param[in,out] poch operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderClaimHandle * -TALER_MERCHANT_order_claim ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, - const struct TALER_ClaimTokenP *claim_token, - TALER_MERCHANT_OrderClaimCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_claim_start ( + struct TALER_MERCHANT_PostOrdersClaimHandle *poch, + TALER_MERCHANT_PostOrdersClaimCallback cb, + TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /orders/$ORDER_ID/claim request. + * Cancel POST /orders/$ORDER_ID/claim operation. This function must not be + * called by clients after the TALER_MERCHANT_PostOrdersClaimCallback has + * been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] och handle to cancel + * @param[in] poch operation to cancel */ void -TALER_MERCHANT_order_claim_cancel ( - struct TALER_MERCHANT_OrderClaimHandle *och); +TALER_MERCHANT_post_orders_claim_cancel ( + struct TALER_MERCHANT_PostOrdersClaimHandle *poch); -#endif +#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_CLAIM_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-paid-new.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-paid-new.h @@ -1,225 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-orders-ORDER_ID-paid-new.h - * @brief C interface for the POST /orders/$ORDER_ID/paid endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAID_NEW_H -#define _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /orders/$ORDER_ID/paid request. - */ -enum TALER_MERCHANT_PostOrdersPaidOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_ORDERS_PAID_OPTION_END = 0, - - /** - * Hash of wallet-specific data. - */ - TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH - -}; - - -/** - * Value for an option for the POST /orders/$ORDER_ID/paid request. - */ -struct TALER_MERCHANT_PostOrdersPaidOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostOrdersPaidOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH. - */ - const struct GNUNET_HashCode *wallet_data_hash; - - } details; - -}; - - -/** - * Handle for a POST /orders/$ORDER_ID/paid request. - */ -struct TALER_MERCHANT_PostOrdersPaidHandle; - - -/** - * Response details for a POST /orders/$ORDER_ID/paid request. - */ -struct TALER_MERCHANT_PostOrdersPaidResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PostOrdersPaidOptionValue - */ -#define TALER_MERCHANT_post_orders_paid_option_end_() \ - (const struct TALER_MERCHANT_PostOrdersPaidOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAID_OPTION_END \ - } - -/** - * Set hash of wallet-specific data. - * - * @param h hash of wallet data, or NULL - * @return representation of the option as a struct TALER_MERCHANT_PostOrdersPaidOptionValue - */ -#define TALER_MERCHANT_post_orders_paid_option_wallet_data_hash(h) \ - (const struct TALER_MERCHANT_PostOrdersPaidOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH, \ - .details.wallet_data_hash = (h) \ - } - - -/** - * Set the requested options for the operation. - * - * @param poph 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_orders_paid_set_options_ ( - struct TALER_MERCHANT_PostOrdersPaidHandle *poph, - unsigned int num_options, - const struct TALER_MERCHANT_PostOrdersPaidOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param poph 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_orders_paid_set_options(poph,...) \ - TALER_MERCHANT_post_orders_paid_set_options_ ( \ - poph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostOrdersPaidOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_orders_paid_option_end_ () } \ - )) - - -/** - * Set up POST /orders/$ORDER_ID/paid operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order - * @param session_id session identifier - * @param h_contract_terms hash of the contract terms - * @param merchant_sig merchant signature over the session data - * @return handle to operation - */ -struct TALER_MERCHANT_PostOrdersPaidHandle * -TALER_MERCHANT_post_orders_paid_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const char *session_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_MerchantSignatureP *merchant_sig); - - -#ifndef TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostOrdersPaidCallback. - */ -#define TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE */ - -/** - * Callback for a POST /orders/$ORDER_ID/paid request. - * - * @param cls closure - * @param opr response details - */ -typedef void -(*TALER_MERCHANT_PostOrdersPaidCallback)( - TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostOrdersPaidResponse *opr); - - -/** - * Start POST /orders/$ORDER_ID/paid operation. - * - * @param[in,out] poph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_paid_start ( - struct TALER_MERCHANT_PostOrdersPaidHandle *poph, - TALER_MERCHANT_PostOrdersPaidCallback cb, - TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /orders/$ORDER_ID/paid operation. This function must not be - * called by clients after the TALER_MERCHANT_PostOrdersPaidCallback has - * been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] poph operation to cancel - */ -void -TALER_MERCHANT_post_orders_paid_cancel ( - struct TALER_MERCHANT_PostOrdersPaidHandle *poph); - - -#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAID_NEW_H */ 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 @@ -16,8 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-orders-ORDER_ID-paid.h - * @brief C interface for POST /orders/$ORDER_ID/paid of the merchant backend - * @author Jonathan Buchanan + * @brief C interface for the POST /orders/$ORDER_ID/paid endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAID_H @@ -27,36 +26,45 @@ /** - * Handle for a POST /orders/$ORDER_ID/paid request. + * Possible options for the POST /orders/$ORDER_ID/paid request. */ -struct TALER_MERCHANT_OrderPaidHandle; +enum TALER_MERCHANT_PostOrdersPaidOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_ORDERS_PAID_OPTION_END = 0, + + /** + * Hash of wallet-specific data. + */ + TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH + +}; /** - * Response details for a POST /orders/$ORDER_ID/paid request. + * Value for an option for the POST /orders/$ORDER_ID/paid request. */ -struct TALER_MERCHANT_OrderPaidResponse +struct TALER_MERCHANT_PostOrdersPaidOptionValue { /** - * HTTP response details. + * Type of the option being set. */ - struct TALER_MERCHANT_HttpResponse hr; + enum TALER_MERCHANT_PostOrdersPaidOption option; /** - * Details depending on the HTTP status code. + * Specific option value. */ union { /** - * Details on #MHD_HTTP_OK. + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH. */ - struct - { - /* currently empty */ - int _dummy; - } ok; + const struct GNUNET_HashCode *wallet_data_hash; } details; @@ -64,53 +72,154 @@ struct TALER_MERCHANT_OrderPaidResponse /** - * Callback for a POST /orders/$ORDER_ID/paid request. + * Handle for a POST /orders/$ORDER_ID/paid request. + */ +struct TALER_MERCHANT_PostOrdersPaidHandle; + + +/** + * Response details for a POST /orders/$ORDER_ID/paid request. + */ +struct TALER_MERCHANT_PostOrdersPaidResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. * - * @param cls closure - * @param opr response details + * @return the terminating object of struct TALER_MERCHANT_PostOrdersPaidOptionValue */ -typedef void -(*TALER_MERCHANT_OrderPaidCallback)( - void *cls, - const struct TALER_MERCHANT_OrderPaidResponse *opr); +#define TALER_MERCHANT_post_orders_paid_option_end_() \ + (const struct TALER_MERCHANT_PostOrdersPaidOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAID_OPTION_END \ + } + +/** + * Set hash of wallet-specific data. + * + * @param h hash of wallet data, or NULL + * @return representation of the option as a struct TALER_MERCHANT_PostOrdersPaidOptionValue + */ +#define TALER_MERCHANT_post_orders_paid_option_wallet_data_hash(h) \ + (const struct TALER_MERCHANT_PostOrdersPaidOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH, \ + .details.wallet_data_hash = (h) \ + } + + +/** + * Set the requested options for the operation. + * + * @param poph 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_orders_paid_set_options_ ( + struct TALER_MERCHANT_PostOrdersPaidHandle *poph, + unsigned int num_options, + const struct TALER_MERCHANT_PostOrdersPaidOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param poph 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_orders_paid_set_options(poph,...) \ + TALER_MERCHANT_post_orders_paid_set_options_ ( \ + poph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostOrdersPaidOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_orders_paid_option_end_ () } \ + )) /** - * Issue a POST /orders/$ORDER_ID/paid request to confirm payment - * (used for session-based repurchase detection). + * Set up POST /orders/$ORDER_ID/paid operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param merchant_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param order_id identifier of the order * @param session_id session identifier * @param h_contract_terms hash of the contract terms - * @param wallet_data_hash hash of wallet-specific data, or NULL * @param merchant_sig merchant signature over the session data - * @param paid_cb callback to invoke with the result - * @param paid_cb_cls closure for @a paid_cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_OrderPaidHandle * -TALER_MERCHANT_order_paid ( +struct TALER_MERCHANT_PostOrdersPaidHandle * +TALER_MERCHANT_post_orders_paid_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, + const char *url, const char *order_id, const char *session_id, const struct TALER_PrivateContractHashP *h_contract_terms, - const struct GNUNET_HashCode *wallet_data_hash, - const struct TALER_MerchantSignatureP *merchant_sig, - TALER_MERCHANT_OrderPaidCallback paid_cb, - void *paid_cb_cls); + const struct TALER_MerchantSignatureP *merchant_sig); + + +#ifndef TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostOrdersPaidCallback. + */ +#define TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE */ + +/** + * Callback for a POST /orders/$ORDER_ID/paid request. + * + * @param cls closure + * @param opr response details + */ +typedef void +(*TALER_MERCHANT_PostOrdersPaidCallback)( + TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostOrdersPaidResponse *opr); + + +/** + * Start POST /orders/$ORDER_ID/paid operation. + * + * @param[in,out] poph operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_paid_start ( + struct TALER_MERCHANT_PostOrdersPaidHandle *poph, + TALER_MERCHANT_PostOrdersPaidCallback cb, + TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /orders/$ORDER_ID/paid request. + * Cancel POST /orders/$ORDER_ID/paid operation. This function must not be + * called by clients after the TALER_MERCHANT_PostOrdersPaidCallback has + * been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] oph handle to cancel + * @param[in] poph operation to cancel */ void -TALER_MERCHANT_order_paid_cancel ( - struct TALER_MERCHANT_OrderPaidHandle *oph); +TALER_MERCHANT_post_orders_paid_cancel ( + struct TALER_MERCHANT_PostOrdersPaidHandle *poph); -#endif +#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAID_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-pay-new.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-pay-new.h @@ -1,714 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-orders-ORDER_ID-pay-new.h - * @brief C interface for the POST /orders/$ORDER_ID/pay endpoint - * @author Christian Grothoff - * @author Marcello Stanisci - */ -#ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAY_NEW_H -#define _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAY_NEW_H - -#include <taler/taler-merchant/common.h> - -/** - * Forward-declaration here to keep the API stable even if - * the Donau header is not available. - */ -struct DONAU_BlindedUniqueDonorIdentifierKeyPair; - -/** - * One coin used to pay (frontend / external wallet mode). - */ -struct TALER_MERCHANT_PostOrdersPayPaidCoin -{ - - /** - * Denomination public key. - */ - struct TALER_DenominationPublicKey denom_pub; - - /** - * Hash of the denomination public key. - */ - struct TALER_DenominationHashP denom_pub_hash; - - /** - * Denomination signature over the coin. - */ - struct TALER_DenominationSignature denom_sig; - - /** - * Face value of the denomination. - */ - struct TALER_Amount denom_value; - - /** - * Public key of the coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Signature by the coin authorizing the deposit. - */ - struct TALER_CoinSpendSignatureP coin_sig; - - /** - * Hash of the age commitment for this coin. - */ - struct TALER_AgeCommitmentHashP h_age_commitment; - - /** - * Set to true if this coin has an age commitment. - */ - bool has_age_commitment; - - /** - * Total amount contributed including deposit fee. - */ - struct TALER_Amount amount_with_fee; - - /** - * Amount contributed without the deposit fee. - */ - struct TALER_Amount amount_without_fee; - - /** - * Deposit fee for this coin. - */ - struct TALER_Amount deposit_fee; - - /** - * Base URL of the exchange this coin was issued by. - */ - char *exchange_url; - -}; - - -/** - * One coin used to pay (wallet-internal mode, private key available). - */ -struct TALER_MERCHANT_PostOrdersPayCoin -{ - - /** - * Denomination public key. - */ - struct TALER_DenominationPublicKey denom_pub; - - /** - * Denomination signature over the coin. - */ - struct TALER_DenominationSignature denom_sig; - - /** - * Face value of the denomination. - */ - struct TALER_Amount denom_value; - - /** - * Private key of the coin (to sign the deposit). - */ - struct TALER_CoinSpendPrivateKeyP coin_priv; - - /** - * Hash of the age commitment for this coin, or - * all zeros if none. - */ - struct TALER_AgeCommitmentHashP h_age_commitment; - - /** - * Total amount contributed including deposit fee. - */ - struct TALER_Amount amount_with_fee; - - /** - * Amount contributed without the deposit fee. - */ - struct TALER_Amount amount_without_fee; - - /** - * URL of the exchange that issued @e coin_priv. - */ - char *exchange_url; - -}; - - -/** - * Token to use for payment (public form, already obtained). - */ -struct TALER_MERCHANT_PostOrdersPayUsedToken -{ - - /** - * Signature on TALER_TokenUseRequestPS made with the token use private key. - */ - struct TALER_TokenUseSignatureP token_sig; - - /** - * Public key of the token. - */ - struct TALER_TokenUsePublicKeyP token_pub; - - /** - * Unblinded signature made by the token issue public key of the merchant. - */ - struct TALER_TokenIssueSignature ub_sig; - - /** - * Token issue public key associated with this token. - */ - struct TALER_TokenIssuePublicKey issue_pub; - -}; - - -/** - * Information we need from the wallet to use a token for an order. - */ -struct TALER_MERCHANT_PostOrdersPayUseToken -{ - - /** - * Private key of the token (to sign the use authorization). - */ - struct TALER_TokenUsePrivateKeyP token_priv; - - /** - * Unblinded signature made by the token issue public key of the merchant. - */ - struct TALER_TokenIssueSignature ub_sig; - - /** - * Token issue public key associated with this token. - */ - struct TALER_TokenIssuePublicKey issue_pub; - -}; - - -/** - * Output token: used both as input to pay (envelope to be signed) - * and as output in the pay response (blind signature received). - */ -struct TALER_MERCHANT_PostOrdersPayOutputToken -{ - - /** - * Blinded token envelope to be signed by the issuer (input to pay). - */ - struct TALER_TokenEnvelope envelope; - - /** - * Blinded token issue signature received from the issuer (output of pay). - */ - struct TALER_BlindedTokenIssueSignature blinded_sig; - -}; - - -/** - * Possible options for the POST /orders/$ORDER_ID/pay request. - */ -enum TALER_MERCHANT_PostOrdersPayOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_END = 0, - - /** - * Session identifier for session-bound payments. - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID, - - /** - * Wallet-specific data (JSON). - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA, - - /** - * Used tokens (public form, for frontend mode). - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS, - - /** - * Use tokens (private form, for wallet mode). - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS, - - /** - * Output tokens (for wallet mode). - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS, - - /** - * Output tokens as JSON array (for frontend mode). - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON, - - /** - * Output donation receipts. - */ - TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU - -}; - - -/** - * Value for an option for the POST /orders/$ORDER_ID/pay request. - */ -struct TALER_MERCHANT_PostOrdersPayOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostOrdersPayOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID. - */ - const char *session_id; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA. - */ - const json_t *wallet_data; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS. - */ - struct - { - /** - * Length of @e tokens array - */ - unsigned int num; - const struct TALER_MERCHANT_PostOrdersPayUsedToken *tokens; - } used_tokens; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS. - */ - struct - { - /** - * Length of @e tokens array - */ - unsigned int num; - const struct TALER_MERCHANT_PostOrdersPayUseToken *tokens; - } use_tokens; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS. - */ - struct - { - /** - * Length of @e tokens array - */ - unsigned int num; - const struct TALER_MERCHANT_PostOrdersPayOutputToken *tokens; - } output_tokens; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON. - */ - json_t *output_tokens_json; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU. - */ - struct - { - /** - * Base URL of the donau. - */ - const char *donau_base_url; - - /** - * Array of blinded dontation receipts. - */ - const struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkps; - - /** - * Length of @e bkps array - */ - size_t num_bkps; - - /** - * Year for which the donation receipts are issued. - */ - uint64_t year; - } output_donau; - - } details; - -}; - - -/** - * Handle for a POST /orders/$ORDER_ID/pay request. - */ -struct TALER_MERCHANT_PostOrdersPayHandle; - - -/** - * Response details for a POST /orders/$ORDER_ID/pay request. - */ -struct TALER_MERCHANT_PostOrdersPayResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Merchant signature confirming the payment. - */ - struct TALER_MerchantSignatureP merchant_sig; - - /** - * POS confirmation string, or NULL if not applicable. - */ - const char *pos_confirmation; - - /** - * Number of output tokens in @a tokens. - */ - unsigned int num_tokens; - - /** - * Array of output tokens issued upon payment. - */ - struct TALER_MERCHANT_PostOrdersPayOutputToken *tokens; - - } ok; - - /** - * Details on #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. - */ - struct - { - - /** - * Number of exchange URLs in @a exchanges. - */ - unsigned int num_exchanges; - - /** - * Array of exchange URLs that refused the payment for legal reasons. - */ - const char **exchanges; - - } unavailable_for_legal_reasons; - - } details; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_orders_pay_option_end_() \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_END \ - } - -/** - * Set session identifier. - * - * @param s session ID - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_session_id(s) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID, \ - .details.session_id = (s) \ - } - -/** - * Set wallet-specific data. - * - * @param w wallet data JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_wallet_data(w) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA, \ - .details.wallet_data = (w) \ - } - -/** - * Set used tokens (public form, for frontend mode). - * - * @param n number of tokens - * @param t array of used tokens - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_used_tokens(n,t) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS, \ - .details.used_tokens = { .num = (n), .tokens = (t) } \ - } - -/** - * Set use tokens (private form, for wallet mode). - * - * @param n number of tokens - * @param t array of use tokens - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_use_tokens(n,t) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS, \ - .details.use_tokens = { .num = (n), .tokens = (t) } \ - } - -/** - * Set output tokens (for wallet mode). - * - * @param n number of output tokens - * @param t array of output tokens - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_output_tokens(n,t) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS, \ - .details.output_tokens = { .num = (n), .tokens = (t) } \ - } - -/** - * Set output tokens as JSON array (for frontend mode). - * - * @param j JSON array describing desired output tokens - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_output_tokens_json(j) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON, \ - .details.output_tokens_json = (j) \ - } - - -/** - * Set blinded donation receipts as output. - * - * @param u base URL of the selected Donau - * @param y year for which receipts are requested - * @param l length of the @a bkps array - * @param a array of blinded donation receipts - * @return representation of the option - */ -#define TALER_MERCHANT_post_orders_pay_option_output_donau(u,y,l,a) \ - (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU, \ - .details.output_donau.donau_base_url = (u), \ - .details.output_donau.bkps = (a), \ - .details.output_donau.num_bkps = (l), \ - .details.output_donau.year = (y) \ - } - - -/** - * Set the requested options for the operation. - * - * @param poph 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_orders_pay_set_options_ ( - struct TALER_MERCHANT_PostOrdersPayHandle *poph, - unsigned int num_options, - const struct TALER_MERCHANT_PostOrdersPayOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param poph 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_orders_pay_set_options(poph,...) \ - TALER_MERCHANT_post_orders_pay_set_options_ ( \ - poph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostOrdersPayOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_orders_pay_option_end_ () } \ - )) - - -/** - * Set up POST /orders/$ORDER_ID/pay operation in frontend mode - * (coins already signed by the wallet). - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to pay - * @param num_coins number of coins in @a coins - * @param coins array of coins to pay with (already signed) - * @return handle to operation - */ -struct TALER_MERCHANT_PostOrdersPayHandle * -TALER_MERCHANT_post_orders_pay_frontend_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - unsigned int num_coins, - const struct TALER_MERCHANT_PostOrdersPayPaidCoin coins[static num_coins]); - - -/** - * Set up POST /orders/$ORDER_ID/pay operation in wallet-internal mode - * (signing done internally). - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to pay - * @param h_contract_terms hash of the contract terms - * @param choice_index payment choice index - * @param amount total payment amount - * @param max_fee maximum acceptable fee - * @param merchant_pub merchant public key - * @param merchant_sig merchant signature - * @param timestamp contract timestamp - * @param refund_deadline refund deadline - * @param pay_deadline payment deadline - * @param h_wire hash of the merchant wire details - * @param num_coins number of coins in @a coins - * @param coins array of coins with private keys - * @return handle to operation - */ -struct TALER_MERCHANT_PostOrdersPayHandle * -TALER_MERCHANT_post_orders_pay_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - int choice_index, // fIXME: make this an option? - const struct TALER_Amount *amount, - const struct TALER_Amount *max_fee, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_MerchantSignatureP *merchant_sig, - struct GNUNET_TIME_Timestamp timestamp, - struct GNUNET_TIME_Timestamp refund_deadline, - struct GNUNET_TIME_Timestamp pay_deadline, - const struct TALER_MerchantWireHashP *h_wire, - unsigned int num_coins, - const struct TALER_MERCHANT_PostOrdersPayCoin coins[static num_coins]); - - -#ifndef TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostOrdersPayCallback. - */ -#define TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE */ - -/** - * Callback for a POST /orders/$ORDER_ID/pay request. - * - * @param cls closure - * @param opr response details - */ -typedef void -(*TALER_MERCHANT_PostOrdersPayCallback)( - TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostOrdersPayResponse *opr); - - -/** - * Start POST /orders/$ORDER_ID/pay operation. - * - * @param[in,out] poph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_pay_start ( - struct TALER_MERCHANT_PostOrdersPayHandle *poph, - TALER_MERCHANT_PostOrdersPayCallback cb, - TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /orders/$ORDER_ID/pay operation. This function must not be - * called by clients after the TALER_MERCHANT_PostOrdersPayCallback has - * been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] poph operation to cancel - */ -void -TALER_MERCHANT_post_orders_pay_cancel ( - struct TALER_MERCHANT_PostOrdersPayHandle *poph); - - -#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAY_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-pay.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-pay.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-orders-ORDER_ID-pay.h - * @brief C interface for POST /orders/$ORDER_ID/pay of the merchant backend + * @brief C interface for the POST /orders/$ORDER_ID/pay endpoint * @author Christian Grothoff * @author Marcello Stanisci */ @@ -25,17 +25,16 @@ #include <taler/taler-merchant/common.h> - /** - * Handle for a POST /orders/$ORDER_ID/pay request. + * Forward-declaration here to keep the API stable even if + * the Donau header is not available. */ -struct TALER_MERCHANT_OrderPayHandle; - +struct DONAU_BlindedUniqueDonorIdentifierKeyPair; /** * One coin used to pay (frontend / external wallet mode). */ -struct TALER_MERCHANT_PaidCoin +struct TALER_MERCHANT_PostOrdersPayPaidCoin { /** @@ -96,7 +95,7 @@ struct TALER_MERCHANT_PaidCoin /** * Base URL of the exchange this coin was issued by. */ - const char *exchange_url; + char *exchange_url; }; @@ -104,7 +103,7 @@ struct TALER_MERCHANT_PaidCoin /** * One coin used to pay (wallet-internal mode, private key available). */ -struct TALER_MERCHANT_PayCoin +struct TALER_MERCHANT_PostOrdersPayCoin { /** @@ -128,9 +127,10 @@ struct TALER_MERCHANT_PayCoin struct TALER_CoinSpendPrivateKeyP coin_priv; /** - * Hash of the age commitment for this coin, or NULL if none. + * Hash of the age commitment for this coin, or + * all zeros if none. */ - const struct TALER_AgeCommitmentHashP *h_age_commitment; + struct TALER_AgeCommitmentHashP h_age_commitment; /** * Total amount contributed including deposit fee. @@ -145,15 +145,248 @@ struct TALER_MERCHANT_PayCoin /** * URL of the exchange that issued @e coin_priv. */ - const char *exchange_url; + char *exchange_url; + +}; + + +/** + * Token to use for payment (public form, already obtained). + */ +struct TALER_MERCHANT_PostOrdersPayUsedToken +{ + + /** + * Signature on TALER_TokenUseRequestPS made with the token use private key. + */ + struct TALER_TokenUseSignatureP token_sig; + + /** + * Public key of the token. + */ + struct TALER_TokenUsePublicKeyP token_pub; + + /** + * Unblinded signature made by the token issue public key of the merchant. + */ + struct TALER_TokenIssueSignature ub_sig; + + /** + * Token issue public key associated with this token. + */ + struct TALER_TokenIssuePublicKey issue_pub; + +}; + + +/** + * Information we need from the wallet to use a token for an order. + */ +struct TALER_MERCHANT_PostOrdersPayUseToken +{ + + /** + * Private key of the token (to sign the use authorization). + */ + struct TALER_TokenUsePrivateKeyP token_priv; + + /** + * Unblinded signature made by the token issue public key of the merchant. + */ + struct TALER_TokenIssueSignature ub_sig; + + /** + * Token issue public key associated with this token. + */ + struct TALER_TokenIssuePublicKey issue_pub; + +}; + + +/** + * Output token: used both as input to pay (envelope to be signed) + * and as output in the pay response (blind signature received). + */ +struct TALER_MERCHANT_PostOrdersPayOutputToken +{ + + /** + * Blinded token envelope to be signed by the issuer (input to pay). + */ + struct TALER_TokenEnvelope envelope; + + /** + * Blinded token issue signature received from the issuer (output of pay). + */ + struct TALER_BlindedTokenIssueSignature blinded_sig; }; /** + * Possible options for the POST /orders/$ORDER_ID/pay request. + */ +enum TALER_MERCHANT_PostOrdersPayOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_END = 0, + + /** + * Session identifier for session-bound payments. + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID, + + /** + * Wallet-specific data (JSON). + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA, + + /** + * Used tokens (public form, for frontend mode). + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS, + + /** + * Use tokens (private form, for wallet mode). + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS, + + /** + * Output tokens (for wallet mode). + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS, + + /** + * Output tokens as JSON array (for frontend mode). + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON, + + /** + * Output donation receipts. + */ + TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU + +}; + + +/** + * Value for an option for the POST /orders/$ORDER_ID/pay request. + */ +struct TALER_MERCHANT_PostOrdersPayOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostOrdersPayOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID. + */ + const char *session_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA. + */ + const json_t *wallet_data; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS. + */ + struct + { + /** + * Length of @e tokens array + */ + unsigned int num; + const struct TALER_MERCHANT_PostOrdersPayUsedToken *tokens; + } used_tokens; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS. + */ + struct + { + /** + * Length of @e tokens array + */ + unsigned int num; + const struct TALER_MERCHANT_PostOrdersPayUseToken *tokens; + } use_tokens; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS. + */ + struct + { + /** + * Length of @e tokens array + */ + unsigned int num; + const struct TALER_MERCHANT_PostOrdersPayOutputToken *tokens; + } output_tokens; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON. + */ + json_t *output_tokens_json; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU. + */ + struct + { + /** + * Base URL of the donau. + */ + const char *donau_base_url; + + /** + * Array of blinded dontation receipts. + */ + const struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkps; + + /** + * Length of @e bkps array + */ + size_t num_bkps; + + /** + * Year for which the donation receipts are issued. + */ + uint64_t year; + } output_donau; + + } details; + +}; + + +/** + * Handle for a POST /orders/$ORDER_ID/pay request. + */ +struct TALER_MERCHANT_PostOrdersPayHandle; + + +/** * Response details for a POST /orders/$ORDER_ID/pay request. */ -struct TALER_MERCHANT_PayResponse +struct TALER_MERCHANT_PostOrdersPayResponse { /** @@ -191,7 +424,7 @@ struct TALER_MERCHANT_PayResponse /** * Array of output tokens issued upon payment. */ - struct TALER_MERCHANT_OutputToken *tokens; + struct TALER_MERCHANT_PostOrdersPayOutputToken *tokens; } ok; @@ -219,131 +452,184 @@ struct TALER_MERCHANT_PayResponse /** - * Token to use for payment (public form, already obtained). + * Terminate the list of the options. + * + * @return the terminating object */ -struct TALER_MERCHANT_UsedToken -{ - - /** - * Signature on TALER_TokenUseRequestPS made with the token use private key. - */ - struct TALER_TokenUseSignatureP token_sig; - - /** - * Public key of the token. This was blindly signed by the merchant - * during the issuance and is now being revealed to the merchant. - */ - struct TALER_TokenUsePublicKeyP token_pub; - - /** - * Unblinded signature made by the token issue public key of the merchant. - */ - struct TALER_TokenIssueSignature ub_sig; - - /** - * Token issue public key associated with this token. - */ - struct TALER_TokenIssuePublicKey issue_pub; -}; +#define TALER_MERCHANT_post_orders_pay_option_end_() \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_END \ + } +/** + * Set session identifier. + * + * @param s session ID + * @return representation of the option + */ +#define TALER_MERCHANT_post_orders_pay_option_session_id(s) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID, \ + .details.session_id = (s) \ + } /** - * Information we need from the wallet to use a token for an order. + * Set wallet-specific data. + * + * @param w wallet data JSON object + * @return representation of the option */ -struct TALER_MERCHANT_UseToken -{ +#define TALER_MERCHANT_post_orders_pay_option_wallet_data(w) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA, \ + .details.wallet_data = (w) \ + } - /** - * Private key of the token (to sign the use authorization). - */ - struct TALER_TokenUsePrivateKeyP token_priv; +/** + * Set used tokens (public form, for frontend mode). + * + * @param n number of tokens + * @param t array of used tokens + * @return representation of the option + */ +#define TALER_MERCHANT_post_orders_pay_option_used_tokens(n,t) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS, \ + .details.used_tokens = { .num = (n), .tokens = (t) } \ + } - /** - * Unblinded signature made by the token issue public key of the merchant. - */ - struct TALER_TokenIssueSignature ub_sig; +/** + * Set use tokens (private form, for wallet mode). + * + * @param n number of tokens + * @param t array of use tokens + * @return representation of the option + */ +#define TALER_MERCHANT_post_orders_pay_option_use_tokens(n,t) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS, \ + .details.use_tokens = { .num = (n), .tokens = (t) } \ + } - /** - * Token issue public key associated with this token. - */ - struct TALER_TokenIssuePublicKey issue_pub; +/** + * Set output tokens (for wallet mode). + * + * @param n number of output tokens + * @param t array of output tokens + * @return representation of the option + */ +#define TALER_MERCHANT_post_orders_pay_option_output_tokens(n,t) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS, \ + .details.output_tokens = { .num = (n), .tokens = (t) } \ + } -}; +/** + * Set output tokens as JSON array (for frontend mode). + * + * @param j JSON array describing desired output tokens + * @return representation of the option + */ +#define TALER_MERCHANT_post_orders_pay_option_output_tokens_json(j) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON, \ + .details.output_tokens_json = (j) \ + } /** - * Output token: used both as input to pay (envelope to be signed) - * and as output in the pay response (blind signature received). + * Set blinded donation receipts as output. + * + * @param u base URL of the selected Donau + * @param y year for which receipts are requested + * @param l length of the @a bkps array + * @param a array of blinded donation receipts + * @return representation of the option */ -struct TALER_MERCHANT_OutputToken -{ - - /** - * Blinded token envelope to be signed by the issuer (input to pay). - */ - struct TALER_TokenEnvelope envelope; +#define TALER_MERCHANT_post_orders_pay_option_output_donau(u,y,l,a) \ + (const struct TALER_MERCHANT_PostOrdersPayOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU, \ + .details.output_donau.donau_base_url = (u), \ + .details.output_donau.bkps = (a), \ + .details.output_donau.num_bkps = (l), \ + .details.output_donau.year = (y) \ + } - /** - * Blinded token issue signature received from the issuer (output of pay). - */ - struct TALER_BlindedTokenIssueSignature blinded_sig; -}; +/** + * Set the requested options for the operation. + * + * @param poph 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_orders_pay_set_options_ ( + struct TALER_MERCHANT_PostOrdersPayHandle *poph, + unsigned int num_options, + const struct TALER_MERCHANT_PostOrdersPayOptionValue *options); /** - * Callback for a POST /orders/$ORDER_ID/pay request. + * Set the requested options for the operation. * - * @param cls closure - * @param opr response details + * @param poph 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 */ -typedef void -(*TALER_MERCHANT_OrderPayCallback)( - void *cls, - const struct TALER_MERCHANT_PayResponse *opr); +#define TALER_MERCHANT_post_orders_pay_set_options(poph,...) \ + TALER_MERCHANT_post_orders_pay_set_options_ ( \ + poph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostOrdersPayOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_orders_pay_option_end_ () } \ + )) /** - * Issue a POST /orders/$ORDER_ID/pay request in frontend mode + * Set up POST /orders/$ORDER_ID/pay operation in frontend mode * (coins already signed by the wallet). + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param merchant_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param order_id identifier of the order to pay - * @param session_id session identifier, or NULL - * @param wallet_data wallet-specific data (JSON), or NULL * @param num_coins number of coins in @a coins * @param coins array of coins to pay with (already signed) - * @param num_tokens number of input tokens in @a tokens - * @param tokens array of tokens to use for payment - * @param j_output_tokens JSON array describing desired output tokens, or NULL - * @param pay_cb callback to invoke with the result - * @param pay_cb_cls closure for @a pay_cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_OrderPayHandle * -TALER_MERCHANT_order_pay_frontend ( +struct TALER_MERCHANT_PostOrdersPayHandle * +TALER_MERCHANT_post_orders_pay_frontend_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, + const char *url, const char *order_id, - const char *session_id, - const json_t *wallet_data, unsigned int num_coins, - const struct TALER_MERCHANT_PaidCoin coins[static num_coins], - unsigned int num_tokens, - const struct TALER_MERCHANT_UsedToken *tokens, - json_t *j_output_tokens, - TALER_MERCHANT_OrderPayCallback pay_cb, - void *pay_cb_cls); + const struct TALER_MERCHANT_PostOrdersPayPaidCoin coins[static num_coins]); /** - * Issue a POST /orders/$ORDER_ID/pay request in wallet-internal mode + * Set up POST /orders/$ORDER_ID/pay operation in wallet-internal mode * (signing done internally). + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param merchant_url base URL of the merchant backend - * @param session_id session identifier, or NULL + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order to pay * @param h_contract_terms hash of the contract terms * @param choice_index payment choice index * @param amount total payment amount @@ -354,24 +640,17 @@ TALER_MERCHANT_order_pay_frontend ( * @param refund_deadline refund deadline * @param pay_deadline payment deadline * @param h_wire hash of the merchant wire details - * @param order_id identifier of the order to pay * @param num_coins number of coins in @a coins * @param coins array of coins with private keys - * @param num_tokens number of input tokens in @a tokens - * @param tokens array of tokens with private keys - * @param num_output_tokens number of output tokens in @a output_tokens - * @param output_tokens array of expected output tokens - * @param pay_cb callback to invoke with the result - * @param pay_cb_cls closure for @a pay_cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_OrderPayHandle * -TALER_MERCHANT_order_pay ( +struct TALER_MERCHANT_PostOrdersPayHandle * +TALER_MERCHANT_post_orders_pay_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, - const char *session_id, + const char *url, + const char *order_id, const struct TALER_PrivateContractHashP *h_contract_terms, - int choice_index, + int choice_index, // fIXME: make this an option? const struct TALER_Amount *amount, const struct TALER_Amount *max_fee, const struct TALER_MerchantPublicKeyP *merchant_pub, @@ -380,25 +659,56 @@ TALER_MERCHANT_order_pay ( struct GNUNET_TIME_Timestamp refund_deadline, struct GNUNET_TIME_Timestamp pay_deadline, const struct TALER_MerchantWireHashP *h_wire, - const char *order_id, unsigned int num_coins, - const struct TALER_MERCHANT_PayCoin coins[static num_coins], - unsigned int num_tokens, - const struct TALER_MERCHANT_UseToken *tokens, - unsigned int num_output_tokens, - const struct TALER_MERCHANT_OutputToken *output_tokens, - TALER_MERCHANT_OrderPayCallback pay_cb, - void *pay_cb_cls); + const struct TALER_MERCHANT_PostOrdersPayCoin coins[static num_coins]); + + +#ifndef TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostOrdersPayCallback. + */ +#define TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE */ + +/** + * Callback for a POST /orders/$ORDER_ID/pay request. + * + * @param cls closure + * @param opr response details + */ +typedef void +(*TALER_MERCHANT_PostOrdersPayCallback)( + TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostOrdersPayResponse *opr); + + +/** + * Start POST /orders/$ORDER_ID/pay operation. + * + * @param[in,out] poph operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_pay_start ( + struct TALER_MERCHANT_PostOrdersPayHandle *poph, + TALER_MERCHANT_PostOrdersPayCallback cb, + TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /orders/$ORDER_ID/pay request. + * Cancel POST /orders/$ORDER_ID/pay operation. This function must not be + * called by clients after the TALER_MERCHANT_PostOrdersPayCallback has + * been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] oph handle to cancel + * @param[in] poph operation to cancel */ void -TALER_MERCHANT_order_pay_cancel ( - struct TALER_MERCHANT_OrderPayHandle *oph); +TALER_MERCHANT_post_orders_pay_cancel ( + struct TALER_MERCHANT_PostOrdersPayHandle *poph); -#endif +#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAY_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-refund-new.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-refund-new.h @@ -1,216 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-orders-ORDER_ID-refund-new.h - * @brief C interface for the POST /orders/$ORDER_ID/refund endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_REFUND_NEW_H -#define _TALER_MERCHANT__POST_ORDERS_ORDER_ID_REFUND_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /orders/$ORDER_ID/refund request. - */ -struct TALER_MERCHANT_PostOrdersRefundHandle; - - -/** - * Details about one refund from the exchange. - */ -struct TALER_MERCHANT_PostOrdersRefundDetail -{ - - /** - * Exchange signature confirming the refund. - */ - struct TALER_ExchangeSignatureP exchange_sig; - - /** - * Exchange public key used for @e exchange_sig. - */ - struct TALER_ExchangePublicKeyP exchange_pub; - - /** - * Hash of the contract terms. - */ - struct TALER_PrivateContractHashP h_contract_terms; - - /** - * Merchant public key. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Refund transaction ID. - */ - uint64_t rtransaction_id; - - /** - * Public key of the refunded coin. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Refund amount. - */ - struct TALER_Amount refund_amount; - - /** - * Refund fee charged by the exchange. - */ - struct TALER_Amount refund_fee; - - /** - * HTTP status returned by the exchange for this refund, 0 if not yet - * obtained. - */ - unsigned int exchange_http_status; - - /** - * Taler error code returned by the exchange. - */ - enum TALER_ErrorCode ec; - - /** - * Full exchange reply (JSON), or NULL. - */ - const json_t *exchange_reply; - - /** - * HTTP response details from the exchange. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Response details for a POST /orders/$ORDER_ID/refund request. - */ -struct TALER_MERCHANT_PostOrdersRefundResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Number of refund details in @a refunds. - */ - unsigned int num_refunds; - - /** - * Array of refund details. - */ - const struct TALER_MERCHANT_PostOrdersRefundDetail *refunds; - - /** - * Merchant public key. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - } ok; - - } details; - -}; - - -/** - * Set up POST /orders/$ORDER_ID/refund operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order - * @param h_contract_terms hash of the contract terms - * @return handle to operation - */ -struct TALER_MERCHANT_PostOrdersRefundHandle * -TALER_MERCHANT_post_orders_refund_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract_terms); - - -#ifndef TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostOrdersRefundCallback. - */ -#define TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE */ - -/** - * Callback for a POST /orders/$ORDER_ID/refund request. - * - * @param cls closure - * @param orr response details - */ -typedef void -(*TALER_MERCHANT_PostOrdersRefundCallback)( - TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostOrdersRefundResponse *orr); - - -/** - * Start POST /orders/$ORDER_ID/refund operation. - * - * @param[in,out] porh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_refund_start ( - struct TALER_MERCHANT_PostOrdersRefundHandle *porh, - TALER_MERCHANT_PostOrdersRefundCallback cb, - TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /orders/$ORDER_ID/refund operation. This function must not be - * called by clients after the TALER_MERCHANT_PostOrdersRefundCallback has - * been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] porh operation to cancel - */ -void -TALER_MERCHANT_post_orders_refund_cancel ( - struct TALER_MERCHANT_PostOrdersRefundHandle *porh); - - -#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_REFUND_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-orders-ORDER_ID-refund.h b/src/include/taler/taler-merchant/post-orders-ORDER_ID-refund.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-orders-ORDER_ID-refund.h - * @brief C interface for POST /orders/$ORDER_ID/refund (wallet-facing) of the merchant backend + * @brief C interface for the POST /orders/$ORDER_ID/refund endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_REFUND_H @@ -26,68 +26,85 @@ /** - * Refund detail in a wallet refund response. + * Handle for a POST /orders/$ORDER_ID/refund request. */ -struct TALER_MERCHANT_RefundDetail +struct TALER_MERCHANT_PostOrdersRefundHandle; + + +/** + * Details about one refund from the exchange. + */ +struct TALER_MERCHANT_PostOrdersRefundDetail { /** - * Exchange response details. Full details are only included - * upon failure (HTTP status is not #MHD_HTTP_OK). + * Exchange signature confirming the refund. */ - struct TALER_EXCHANGE_HttpResponse hr; + struct TALER_ExchangeSignatureP exchange_sig; /** - * Coin this detail is about. + * Exchange public key used for @e exchange_sig. */ - struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * Hash of the contract terms. + */ + struct TALER_PrivateContractHashP h_contract_terms; /** - * Refund transaction ID used. + * Merchant public key. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Refund transaction ID. */ uint64_t rtransaction_id; /** - * Amount to be refunded for this coin. + * Public key of the refunded coin. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Refund amount. */ struct TALER_Amount refund_amount; /** - * Details depending on exchange HTTP status. + * Refund fee charged by the exchange. */ - union - { - /** - * Details if exchange status is #MHD_HTTP_OK. - */ - struct - { - /** - * Public key of the exchange affirming the refund, - * only valid if the @e hr http_status is #MHD_HTTP_OK. - */ - struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_Amount refund_fee; - /** - * Signature of the exchange affirming the refund, - * only valid if the @e hr http_status is #MHD_HTTP_OK. - */ - struct TALER_ExchangeSignatureP exchange_sig; - } ok; - } details; -}; + /** + * HTTP status returned by the exchange for this refund, 0 if not yet + * obtained. + */ + unsigned int exchange_http_status; + /** + * Taler error code returned by the exchange. + */ + enum TALER_ErrorCode ec; -/** - * Handle for a POST /orders/$ORDER_ID/refund request (wallet-facing). - */ -struct TALER_MERCHANT_WalletOrderRefundHandle; + /** + * Full exchange reply (JSON), or NULL. + */ + const json_t *exchange_reply; + + /** + * HTTP response details from the exchange. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; /** - * Response details for a POST /orders/$ORDER_ID/refund request (wallet-facing). + * Response details for a POST /orders/$ORDER_ID/refund request. */ -struct TALER_MERCHANT_WalletRefundResponse +struct TALER_MERCHANT_PostOrdersRefundResponse { /** @@ -108,24 +125,19 @@ struct TALER_MERCHANT_WalletRefundResponse { /** - * Total amount refunded. + * Number of refund details in @a refunds. */ - struct TALER_Amount refund_amount; - - /** - * Public key of the merchant. - */ - struct TALER_MerchantPublicKeyP merchant_pub; + unsigned int num_refunds; /** - * Number of per-coin refund details in @a refunds. + * Array of refund details. */ - unsigned int refunds_length; + const struct TALER_MERCHANT_PostOrdersRefundDetail *refunds; /** - * Array of per-coin refund details. + * Merchant public key. */ - const struct TALER_MERCHANT_RefundDetail *refunds; + struct TALER_MerchantPublicKeyP merchant_pub; } ok; @@ -135,47 +147,70 @@ struct TALER_MERCHANT_WalletRefundResponse /** - * Callback for a POST /orders/$ORDER_ID/refund request (wallet-facing). + * Set up POST /orders/$ORDER_ID/refund operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order + * @param h_contract_terms hash of the contract terms + * @return handle to operation + */ +struct TALER_MERCHANT_PostOrdersRefundHandle * +TALER_MERCHANT_post_orders_refund_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct TALER_PrivateContractHashP *h_contract_terms); + + +#ifndef TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostOrdersRefundCallback. + */ +#define TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE */ + +/** + * Callback for a POST /orders/$ORDER_ID/refund request. * * @param cls closure - * @param wrr response details + * @param orr response details */ typedef void -(*TALER_MERCHANT_WalletRefundCallback)( - void *cls, - const struct TALER_MERCHANT_WalletRefundResponse *wrr); +(*TALER_MERCHANT_PostOrdersRefundCallback)( + TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostOrdersRefundResponse *orr); /** - * Issue a POST /orders/$ORDER_ID/refund request (wallet-facing) to - * obtain refund signatures. + * Start POST /orders/$ORDER_ID/refund operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order_id identifier of the order to refund - * @param h_contract_terms hash of the contract terms - * @param cb callback to invoke with the result + * @param[in,out] porh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_WalletOrderRefundHandle * -TALER_MERCHANT_wallet_post_order_refund ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - TALER_MERCHANT_WalletRefundCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_refund_start ( + struct TALER_MERCHANT_PostOrdersRefundHandle *porh, + TALER_MERCHANT_PostOrdersRefundCallback cb, + TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /orders/$ORDER_ID/refund request (wallet-facing). + * Cancel POST /orders/$ORDER_ID/refund operation. This function must not be + * called by clients after the TALER_MERCHANT_PostOrdersRefundCallback has + * been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] orh handle to cancel + * @param[in] porh operation to cancel */ void -TALER_MERCHANT_wallet_post_order_refund_cancel ( - struct TALER_MERCHANT_WalletOrderRefundHandle *orh); +TALER_MERCHANT_post_orders_refund_cancel ( + struct TALER_MERCHANT_PostOrdersRefundHandle *porh); -#endif +#endif /* _TALER_MERCHANT__POST_ORDERS_ORDER_ID_REFUND_H */ diff --git a/src/include/taler/taler-merchant/post-private-accounts-new.h b/src/include/taler/taler-merchant/post-private-accounts-new.h @@ -1,271 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-accounts-new.h - * @brief C interface for the POST /private/accounts endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_ACCOUNTS_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_ACCOUNTS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/accounts request. - */ -enum TALER_MERCHANT_PostPrivateAccountsOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_END = 0, - - /** - * URL of the credit facade. - */ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL, - - /** - * Credentials for the credit facade (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS - -}; - - -/** - * Value for an option for the POST /private/accounts request. - */ -struct TALER_MERCHANT_PostPrivateAccountsOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateAccountsOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL. - */ - const char *credit_facade_url; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS. - */ - const json_t *credit_facade_credentials; - - } details; - -}; - - -/** - * Handle for a POST /private/accounts request. - */ -struct TALER_MERCHANT_PostPrivateAccountsHandle; - - -/** - * Response details for a POST /private/accounts request. - */ -struct TALER_MERCHANT_PostPrivateAccountsResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Hash of the wire details for the newly created account. - */ - struct TALER_MerchantWireHashP h_wire; - - /** - * Salt used in the wire hash computation. - */ - struct TALER_WireSaltP salt; - - } ok; - - } details; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PostPrivateAccountsOptionValue - */ -#define TALER_MERCHANT_post_private_accounts_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_END \ - } - -/** - * Set credit facade URL. - * - * @param u credit facade URL - * @return representation of the option as a struct TALER_MERCHANT_PostPrivateAccountsOptionValue - */ -#define TALER_MERCHANT_post_private_accounts_option_credit_facade_url(u) \ - (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL, \ - .details.credit_facade_url = (u) \ - } - -/** - * Set credit facade credentials. - * - * @param c credentials JSON object - * @return representation of the option as a struct TALER_MERCHANT_PostPrivateAccountsOptionValue - */ -#define TALER_MERCHANT_post_private_accounts_option_credit_facade_credentials(c) \ - (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS, \ - .details.credit_facade_credentials = (c) \ - } - - -/** - * Set the requested options for the operation. - * - * @param ppah 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_accounts_set_options_ ( - struct TALER_MERCHANT_PostPrivateAccountsHandle *ppah, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateAccountsOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ppah 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_accounts_set_options(ppah,...) \ - TALER_MERCHANT_post_private_accounts_set_options_ ( \ - ppah, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateAccountsOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_accounts_option_end_ () } \ - )) - - -/** - * Set up POST /private/accounts operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param payto_uri payto URI of the account to add - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateAccountsHandle * -TALER_MERCHANT_post_private_accounts_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - struct TALER_FullPayto payto_uri); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateAccountsCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/accounts request. - * - * @param cls closure - * @param apr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateAccountsCallback)( - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateAccountsResponse *apr); - - -/** - * Start POST /private/accounts operation. - * - * @param[in,out] ppah operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_accounts_start ( - struct TALER_MERCHANT_PostPrivateAccountsHandle *ppah, - TALER_MERCHANT_PostPrivateAccountsCallback cb, - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/accounts operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateAccountsCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppah operation to cancel - */ -void -TALER_MERCHANT_post_private_accounts_cancel ( - struct TALER_MERCHANT_PostPrivateAccountsHandle *ppah); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_ACCOUNTS_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-accounts.h b/src/include/taler/taler-merchant/post-private-accounts.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-accounts.h - * @brief C interface for POST /private/accounts of the merchant backend + * @brief C interface for the POST /private/accounts endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_ACCOUNTS_H @@ -26,15 +26,72 @@ /** + * Possible options for the POST /private/accounts request. + */ +enum TALER_MERCHANT_PostPrivateAccountsOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_END = 0, + + /** + * URL of the credit facade. + */ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL, + + /** + * Credentials for the credit facade (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS + +}; + + +/** + * Value for an option for the POST /private/accounts request. + */ +struct TALER_MERCHANT_PostPrivateAccountsOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateAccountsOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL. + */ + const char *credit_facade_url; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS. + */ + const json_t *credit_facade_credentials; + + } details; + +}; + + +/** * Handle for a POST /private/accounts request. */ -struct TALER_MERCHANT_AccountsPostHandle; +struct TALER_MERCHANT_PostPrivateAccountsHandle; /** * Response details for a POST /private/accounts request. */ -struct TALER_MERCHANT_AccountsPostResponse +struct TALER_MERCHANT_PostPrivateAccountsResponse { /** @@ -72,48 +129,143 @@ struct TALER_MERCHANT_AccountsPostResponse /** + * Terminate the list of the options. + * + * @return the terminating object of struct TALER_MERCHANT_PostPrivateAccountsOptionValue + */ +#define TALER_MERCHANT_post_private_accounts_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_END \ + } + +/** + * Set credit facade URL. + * + * @param u credit facade URL + * @return representation of the option as a struct TALER_MERCHANT_PostPrivateAccountsOptionValue + */ +#define TALER_MERCHANT_post_private_accounts_option_credit_facade_url(u) \ + (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_URL, \ + .details.credit_facade_url = (u) \ + } + +/** + * Set credit facade credentials. + * + * @param c credentials JSON object + * @return representation of the option as a struct TALER_MERCHANT_PostPrivateAccountsOptionValue + */ +#define TALER_MERCHANT_post_private_accounts_option_credit_facade_credentials(c) \ + (const struct TALER_MERCHANT_PostPrivateAccountsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS, \ + .details.credit_facade_credentials = (c) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ppah 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_accounts_set_options_ ( + struct TALER_MERCHANT_PostPrivateAccountsHandle *ppah, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateAccountsOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param ppah 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_accounts_set_options(ppah,...) \ + TALER_MERCHANT_post_private_accounts_set_options_ ( \ + ppah, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateAccountsOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_accounts_option_end_ () } \ + )) + + +/** + * Set up POST /private/accounts operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param payto_uri payto URI of the account to add + * @return handle to operation + */ +struct TALER_MERCHANT_PostPrivateAccountsHandle * +TALER_MERCHANT_post_private_accounts_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_FullPayto payto_uri); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateAccountsCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE */ + +/** * Callback for a POST /private/accounts request. * * @param cls closure * @param apr response details */ typedef void -(*TALER_MERCHANT_AccountsPostCallback)( - void *cls, - const struct TALER_MERCHANT_AccountsPostResponse *apr); +(*TALER_MERCHANT_PostPrivateAccountsCallback)( + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateAccountsResponse *apr); /** - * Issue a POST /private/accounts request to add a wire account. + * Start POST /private/accounts operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param payto_uri payto URI of the account to add - * @param credit_facade_url URL of the credit facade, or NULL - * @param credit_facade_credentials credentials for the credit facade (JSON), or NULL - * @param cb callback to invoke with the result + * @param[in,out] ppah operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_AccountsPostHandle * -TALER_MERCHANT_accounts_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - struct TALER_FullPayto payto_uri, - const char *credit_facade_url, - const json_t *credit_facade_credentials, - TALER_MERCHANT_AccountsPostCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_accounts_start ( + struct TALER_MERCHANT_PostPrivateAccountsHandle *ppah, + TALER_MERCHANT_PostPrivateAccountsCallback cb, + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/accounts request. + * Cancel POST /private/accounts operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateAccountsCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] aph handle to cancel + * @param[in] ppah operation to cancel */ void -TALER_MERCHANT_accounts_post_cancel ( - struct TALER_MERCHANT_AccountsPostHandle *aph); +TALER_MERCHANT_post_private_accounts_cancel ( + struct TALER_MERCHANT_PostPrivateAccountsHandle *ppah); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_ACCOUNTS_H */ diff --git a/src/include/taler/taler-merchant/post-private-categories-new.h b/src/include/taler/taler-merchant/post-private-categories-new.h @@ -1,240 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-categories-new.h - * @brief C interface for the POST /private/categories endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_CATEGORIES_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_CATEGORIES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/categories request. - */ -enum TALER_MERCHANT_PostPrivateCategoriesOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_END = 0, - - /** - * Internationalized names (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N - -}; - - -/** - * Value for an option for the POST /private/categories request. - */ -struct TALER_MERCHANT_PostPrivateCategoriesOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateCategoriesOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N. - */ - const json_t *name_i18n; - - } details; - -}; - - -/** - * Handle for a POST /private/categories request. - */ -struct TALER_MERCHANT_PostPrivateCategoriesHandle; - - -/** - * Response details for a POST /private/categories request. - */ -struct TALER_MERCHANT_PostPrivateCategoriesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Numeric identifier of the newly created category. - */ - uint64_t category_id; - - } ok; - - } details; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_categories_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_END \ - } - -/** - * Set internationalized names. - * - * @param n names JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_categories_option_name_i18n(n) \ - (const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N, \ - .details.name_i18n = (n) \ - } - - -/** - * Set the requested options for the operation. - * - * @param ppch 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_categories_set_options_ ( - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ppch 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_categories_set_options(ppch,...) \ - TALER_MERCHANT_post_private_categories_set_options_ ( \ - ppch, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_categories_option_end_ () } \ - )) - - -/** - * Set up POST /private/categories operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param name human-readable name of the category - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateCategoriesHandle * -TALER_MERCHANT_post_private_categories_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *name); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateCategoriesCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/categories request. - * - * @param cls closure - * @param cpr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateCategoriesCallback)( - TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateCategoriesResponse *cpr); - - -/** - * Start POST /private/categories operation. - * - * @param[in,out] ppch operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_categories_start ( - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, - TALER_MERCHANT_PostPrivateCategoriesCallback cb, - TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/categories operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateCategoriesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppch operation to cancel - */ -void -TALER_MERCHANT_post_private_categories_cancel ( - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_CATEGORIES_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-categories.h b/src/include/taler/taler-merchant/post-private-categories.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-categories.h - * @brief C interface for POST /private/categories of the merchant backend + * @brief C interface for the POST /private/categories endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_CATEGORIES_H @@ -26,15 +26,61 @@ /** + * Possible options for the POST /private/categories request. + */ +enum TALER_MERCHANT_PostPrivateCategoriesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_END = 0, + + /** + * Internationalized names (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N + +}; + + +/** + * Value for an option for the POST /private/categories request. + */ +struct TALER_MERCHANT_PostPrivateCategoriesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateCategoriesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N. + */ + const json_t *name_i18n; + + } details; + +}; + + +/** * Handle for a POST /private/categories request. */ -struct TALER_MERCHANT_CategoriesPostHandle; +struct TALER_MERCHANT_PostPrivateCategoriesHandle; /** * Response details for a POST /private/categories request. */ -struct TALER_MERCHANT_CategoriesPostResponse +struct TALER_MERCHANT_PostPrivateCategoriesResponse { /** @@ -43,54 +89,152 @@ struct TALER_MERCHANT_CategoriesPostResponse struct TALER_MERCHANT_HttpResponse hr; /** - * On #MHD_HTTP_OK, the numeric identifier of the newly created category. + * Details depending on the HTTP status code. */ - uint64_t category_id; + union + { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + + /** + * Numeric identifier of the newly created category. + */ + uint64_t category_id; + + } ok; + + } details; }; /** + * Terminate the list of the options. + * + * @return the terminating object + */ +#define TALER_MERCHANT_post_private_categories_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_END \ + } + +/** + * Set internationalized names. + * + * @param n names JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_categories_option_name_i18n(n) \ + (const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N, \ + .details.name_i18n = (n) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ppch 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_categories_set_options_ ( + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param ppch 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_categories_set_options(ppch,...) \ + TALER_MERCHANT_post_private_categories_set_options_ ( \ + ppch, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_categories_option_end_ () } \ + )) + + +/** + * Set up POST /private/categories operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param name human-readable name of the category + * @return handle to operation + */ +struct TALER_MERCHANT_PostPrivateCategoriesHandle * +TALER_MERCHANT_post_private_categories_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *name); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateCategoriesCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE */ + +/** * Callback for a POST /private/categories request. * * @param cls closure * @param cpr response details */ typedef void -(*TALER_MERCHANT_CategoriesPostCallback)( - void *cls, - const struct TALER_MERCHANT_CategoriesPostResponse *cpr); +(*TALER_MERCHANT_PostPrivateCategoriesCallback)( + TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateCategoriesResponse *cpr); /** - * Issue a POST /private/categories request to create a new product category. + * Start POST /private/categories operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param name human-readable name of the category - * @param name_i18n internationalized names (JSON), or NULL - * @param cb callback to invoke with the result + * @param[in,out] ppch operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_CategoriesPostHandle * -TALER_MERCHANT_categories_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *name, - const json_t *name_i18n, - TALER_MERCHANT_CategoriesPostCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_categories_start ( + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, + TALER_MERCHANT_PostPrivateCategoriesCallback cb, + TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/categories request. + * Cancel POST /private/categories operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateCategoriesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] cph handle to cancel + * @param[in] ppch operation to cancel */ void -TALER_MERCHANT_categories_post_cancel ( - struct TALER_MERCHANT_CategoriesPostHandle *cph); +TALER_MERCHANT_post_private_categories_cancel ( + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_CATEGORIES_H */ diff --git a/src/include/taler/taler-merchant/post-private-donau-new.h b/src/include/taler/taler-merchant/post-private-donau-new.h @@ -1,220 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-donau-new.h - * @brief C interface for the POST /private/donau endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_DONAU_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_DONAU_NEW_H - -#include <taler/taler-merchant/common.h> -#include <taler/taler-merchant/post-private-donau.h> - - -/** - * Possible options for the POST /private/donau request. - */ -enum TALER_MERCHANT_PostPrivateDonauOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_END = 0, - - /** - * Authentication token for the Donau service. - */ - TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN - -}; - - -/** - * Value for an option for the POST /private/donau request. - */ -struct TALER_MERCHANT_PostPrivateDonauOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateDonauOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN. - */ - const char *auth_token; - - } details; - -}; - - -/** - * Handle for a POST /private/donau request. - */ -struct TALER_MERCHANT_PostPrivateDonauHandle; - - -/** - * Response details for a POST /private/donau request. - */ -struct TALER_MERCHANT_PostPrivateDonauResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_donau_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateDonauOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_END \ - } - -/** - * Set authentication token. - * - * @param t authentication token - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_donau_option_auth_token(t) \ - (const struct TALER_MERCHANT_PostPrivateDonauOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN, \ - .details.auth_token = (t) \ - } - - -/** - * Set the requested options for the operation. - * - * @param ppdh 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_donau_set_options_ ( - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateDonauOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ppdh 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_donau_set_options(ppdh,...) \ - TALER_MERCHANT_post_private_donau_set_options_ ( \ - ppdh, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateDonauOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_donau_option_end_ () } \ - )) - - -/** - * Set up POST /private/donau operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param charity charity information to register - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateDonauHandle * -TALER_MERCHANT_post_private_donau_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_MERCHANT_Charity *charity); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateDonauCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/donau request. - * - * @param cls closure - * @param pdr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateDonauCallback)( - TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateDonauResponse *pdr); - - -/** - * Start POST /private/donau operation. - * - * @param[in,out] ppdh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_donau_start ( - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, - TALER_MERCHANT_PostPrivateDonauCallback cb, - TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/donau operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateDonauCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppdh operation to cancel - */ -void -TALER_MERCHANT_post_private_donau_cancel ( - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_DONAU_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-donau.h b/src/include/taler/taler-merchant/post-private-donau.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-donau.h - * @brief C interface for POST /private/donau of the merchant backend + * @brief C interface for the POST /private/donau endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_DONAU_H @@ -26,12 +26,6 @@ /** - * Handle for a POST /private/donau request. - */ -struct TALER_MERCHANT_DonauInstancePostHandle; - - -/** * Donau charity structure for POST /private/donau. */ struct TALER_MERCHANT_Charity @@ -51,47 +45,194 @@ struct TALER_MERCHANT_Charity /** + * Possible options for the POST /private/donau request. + */ +enum TALER_MERCHANT_PostPrivateDonauOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_END = 0, + + /** + * Authentication token for the Donau service. + */ + TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN + +}; + + +/** + * Value for an option for the POST /private/donau request. + */ +struct TALER_MERCHANT_PostPrivateDonauOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateDonauOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN. + */ + const char *auth_token; + + } details; + +}; + + +/** + * Handle for a POST /private/donau request. + */ +struct TALER_MERCHANT_PostPrivateDonauHandle; + + +/** + * Response details for a POST /private/donau request. + */ +struct TALER_MERCHANT_PostPrivateDonauResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. + * + * @return the terminating object + */ +#define TALER_MERCHANT_post_private_donau_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateDonauOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_END \ + } + +/** + * Set authentication token. + * + * @param t authentication token + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_donau_option_auth_token(t) \ + (const struct TALER_MERCHANT_PostPrivateDonauOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN, \ + .details.auth_token = (t) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ppdh 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_donau_set_options_ ( + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateDonauOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param ppdh 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_donau_set_options(ppdh,...) \ + TALER_MERCHANT_post_private_donau_set_options_ ( \ + ppdh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateDonauOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_donau_option_end_ () } \ + )) + + +/** + * Set up POST /private/donau operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param charity charity information to register + * @return handle to operation + */ +struct TALER_MERCHANT_PostPrivateDonauHandle * +TALER_MERCHANT_post_private_donau_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_MERCHANT_Charity *charity); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateDonauCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE */ + +/** * Callback for a POST /private/donau request. * * @param cls closure - * @param hr HTTP response details + * @param pdr response details */ typedef void -(*TALER_MERCHANT_DonauInstancePostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +(*TALER_MERCHANT_PostPrivateDonauCallback)( + TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateDonauResponse *pdr); /** - * Issue a POST /private/donau request to register a Donau charity. + * Start POST /private/donau operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param charity charity information to register - * @param auth_token authentication token for the Donau service, or NULL - * @param cb callback to invoke with the result + * @param[in,out] ppdh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_DonauInstancePostHandle * -TALER_MERCHANT_donau_instances_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MERCHANT_Charity *charity, - const char *auth_token, - TALER_MERCHANT_DonauInstancePostCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_donau_start ( + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, + TALER_MERCHANT_PostPrivateDonauCallback cb, + TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/donau request. - * This must not be called after the callback has been invoked. + * Cancel POST /private/donau operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateDonauCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] dph handle to cancel + * @param[in] ppdh operation to cancel */ void -TALER_MERCHANT_donau_instances_post_cancel ( - struct TALER_MERCHANT_DonauInstancePostHandle *dph); +TALER_MERCHANT_post_private_donau_cancel ( + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_DONAU_H */ diff --git a/src/include/taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h b/src/include/taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h @@ -1,143 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h - * @brief C interface for the POST /private/orders/$ORDER_ID/refund endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_ORDERS_ORDER_ID_REFUND_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_ORDERS_ORDER_ID_REFUND_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /private/orders/$ORDER_ID/refund request. - */ -struct TALER_MERCHANT_PostPrivateOrdersRefundHandle; - - -/** - * Response details for a POST /private/orders/$ORDER_ID/refund request. - */ -struct TALER_MERCHANT_PostPrivateOrdersRefundResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Taler refund URI for the wallet. - */ - const char *taler_refund_uri; - - /** - * Hash of the contract terms for this order. - */ - struct TALER_PrivateContractHashP h_contract; - - } ok; - - } details; - -}; - - -/** - * Set up POST /private/orders/$ORDER_ID/refund operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order_id identifier of the order to refund - * @param refund amount to refund - * @param reason human-readable reason for the refund - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateOrdersRefundHandle * -TALER_MERCHANT_post_private_orders_refund_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_Amount *refund, - const char *reason); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateOrdersRefundCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/orders/$ORDER_ID/refund request. - * - * @param cls closure - * @param rr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateOrdersRefundCallback)( - TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateOrdersRefundResponse *rr); - - -/** - * Start POST /private/orders/$ORDER_ID/refund operation. - * - * @param[in,out] porh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_orders_refund_start ( - struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh, - TALER_MERCHANT_PostPrivateOrdersRefundCallback cb, - TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/orders/$ORDER_ID/refund operation. This function - * must not be called by clients after the - * TALER_MERCHANT_PostPrivateOrdersRefundCallback has been invoked (as in - * those cases it'll be called internally by the implementation already). - * - * @param[in] porh operation to cancel - */ -void -TALER_MERCHANT_post_private_orders_refund_cancel ( - struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_ORDERS_ORDER_ID_REFUND_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-orders-ORDER_ID-refund.h b/src/include/taler/taler-merchant/post-private-orders-ORDER_ID-refund.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-orders-ORDER_ID-refund.h - * @brief C interface for POST /private/orders/$ORDER_ID/refund of the merchant backend + * @brief C interface for the POST /private/orders/$ORDER_ID/refund endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_ORDERS_ORDER_ID_REFUND_H @@ -28,13 +28,13 @@ /** * Handle for a POST /private/orders/$ORDER_ID/refund request. */ -struct TALER_MERCHANT_OrderRefundHandle; +struct TALER_MERCHANT_PostPrivateOrdersRefundHandle; /** * Response details for a POST /private/orders/$ORDER_ID/refund request. */ -struct TALER_MERCHANT_RefundResponse +struct TALER_MERCHANT_PostPrivateOrdersRefundResponse { /** @@ -72,48 +72,72 @@ struct TALER_MERCHANT_RefundResponse /** + * Set up POST /private/orders/$ORDER_ID/refund operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order_id identifier of the order to refund + * @param refund amount to refund + * @param reason human-readable reason for the refund + * @return handle to operation + */ +struct TALER_MERCHANT_PostPrivateOrdersRefundHandle * +TALER_MERCHANT_post_private_orders_refund_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct TALER_Amount *refund, + const char *reason); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateOrdersRefundCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE */ + +/** * Callback for a POST /private/orders/$ORDER_ID/refund request. * * @param cls closure * @param rr response details */ typedef void -(*TALER_MERCHANT_RefundCallback)( - void *cls, - const struct TALER_MERCHANT_RefundResponse *rr); +(*TALER_MERCHANT_PostPrivateOrdersRefundCallback)( + TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateOrdersRefundResponse *rr); /** - * Issue a POST /private/orders/$ORDER_ID/refund request to grant a refund. + * Start POST /private/orders/$ORDER_ID/refund operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order_id identifier of the order to refund - * @param refund amount to refund - * @param reason human-readable reason for the refund - * @param cb callback to invoke with the result + * @param[in,out] porh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_OrderRefundHandle * -TALER_MERCHANT_post_order_refund ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct TALER_Amount *refund, - const char *reason, - TALER_MERCHANT_RefundCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_orders_refund_start ( + struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh, + TALER_MERCHANT_PostPrivateOrdersRefundCallback cb, + TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/orders/$ORDER_ID/refund request. + * Cancel POST /private/orders/$ORDER_ID/refund operation. This function + * must not be called by clients after the + * TALER_MERCHANT_PostPrivateOrdersRefundCallback has been invoked (as in + * those cases it'll be called internally by the implementation already). * - * @param[in] orh handle to cancel + * @param[in] porh operation to cancel */ void -TALER_MERCHANT_post_order_refund_cancel ( - struct TALER_MERCHANT_OrderRefundHandle *orh); +TALER_MERCHANT_post_private_orders_refund_cancel ( + struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_ORDERS_ORDER_ID_REFUND_H */ diff --git a/src/include/taler/taler-merchant/post-private-orders-new.h b/src/include/taler/taler-merchant/post-private-orders-new.h @@ -1,472 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-orders-new.h - * @brief C interface for the POST /private/orders endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_ORDERS_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_ORDERS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * A product from inventory to include in an order. - */ -struct TALER_MERCHANT_PostPrivateOrdersInventoryProduct -{ - - /** - * Identifier of the product. - */ - const char *product_id; - - /** - * Quantity of the product to include. - */ - uint32_t quantity; - - /** - * Fractional part of the quantity. - */ - uint32_t quantity_frac; - - /** - * Whether to use fractional quantity. - */ - bool use_fractional_quantity; - -}; - - -/** - * Possible options for the POST /private/orders request. - */ -enum TALER_MERCHANT_PostPrivateOrdersOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_END = 0, - - /** - * Refund delay. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY, - - /** - * Payment target (type of payment method). - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET, - - /** - * Session identifier for session-bound payments. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID, - - /** - * Whether to create a claim token. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN, - - /** - * OTP device ID. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID, - - /** - * Inventory products to include in the order. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS, - - /** - * Lock UUIDs for inventory locks. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS - -}; - - -/** - * Value for an option for the POST /private/orders request. - */ -struct TALER_MERCHANT_PostPrivateOrdersOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateOrdersOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY. - */ - struct GNUNET_TIME_Relative refund_delay; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET. - */ - const char *payment_target; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID. - */ - const char *session_id; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN. - */ - bool create_token; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID. - */ - const char *otp_id; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS. - */ - struct - { - unsigned int num; - const struct TALER_MERCHANT_PostPrivateOrdersInventoryProduct *products; - } inventory_products; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS. - */ - struct - { - unsigned int num; - const char **uuids; - } lock_uuids; - - } details; - -}; - - -/** - * Handle for a POST /private/orders request. - */ -struct TALER_MERCHANT_PostPrivateOrdersHandle; - - -/** - * Response details for a POST /private/orders request. - */ -struct TALER_MERCHANT_PostPrivateOrdersResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Identifier of the created order. - */ - const char *order_id; - - /** - * Claim token, or NULL. - */ - const struct TALER_ClaimTokenP *token; - - /** - * Payment deadline. - */ - struct GNUNET_TIME_Timestamp pay_deadline; - - } ok; - - /** - * Details on #MHD_HTTP_GONE (product out of stock). - */ - struct - { - - /** - * Product that is out of stock. - */ - const char *product_id; - - /** - * Requested quantity (integer part). - */ - uint64_t requested_quantity; - - /** - * Requested quantity (fractional part). - */ - uint32_t requested_quantity_frac; - - /** - * Available quantity (integer part). - */ - uint64_t available_quantity; - - /** - * Available quantity (fractional part). - */ - uint32_t available_quantity_frac; - - /** - * Expected restock time. - */ - struct GNUNET_TIME_Timestamp restock_expected; - - } gone; - - } details; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_orders_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_END \ - } - -/** - * Set refund delay. - * - * @param d refund delay - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_refund_delay(d) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY, \ - .details.refund_delay = (d) \ - } - -/** - * Set payment target. - * - * @param t payment target string - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_payment_target(t) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET, \ - .details.payment_target = (t) \ - } - -/** - * Set session identifier. - * - * @param s session ID - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_session_id(s) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID, \ - .details.session_id = (s) \ - } - -/** - * Set whether to create a claim token. - * - * @param c true to create token - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_create_token(c) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN, \ - .details.create_token = (c) \ - } - -/** - * Set OTP device ID. - * - * @param o OTP device ID - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_otp_id(o) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID, \ - .details.otp_id = (o) \ - } - -/** - * Set inventory products. - * - * @param n number of products - * @param p array of inventory products - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_inventory_products(n,p) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS \ - , \ - .details.inventory_products = { .num = (n), .products = (p) } \ - } - -/** - * Set lock UUIDs. - * - * @param n number of UUIDs - * @param u array of UUID strings - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_orders_option_lock_uuids(n,u) \ - (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS, \ - .details.lock_uuids = { .num = (n), .uuids = (u) } \ - } - - -/** - * Set the requested options for the operation. - * - * @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_orders_set_options_ ( - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateOrdersOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ppoh 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_orders_set_options(ppoh,...) \ - TALER_MERCHANT_post_private_orders_set_options_ ( \ - ppoh, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateOrdersOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_orders_option_end_ () } \ - )) - - -/** - * Set up POST /private/orders operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param order order contract (JSON) - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateOrdersHandle * -TALER_MERCHANT_post_private_orders_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const json_t *order); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateOrdersCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/orders request. - * - * @param cls closure - * @param por response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateOrdersCallback)( - TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateOrdersResponse *por); - - -/** - * Start POST /private/orders operation. - * - * @param[in,out] ppoh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_orders_start ( - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, - TALER_MERCHANT_PostPrivateOrdersCallback cb, - TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/orders operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateOrdersCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppoh operation to cancel - */ -void -TALER_MERCHANT_post_private_orders_cancel ( - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_ORDERS_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-orders.h b/src/include/taler/taler-merchant/post-private-orders.h @@ -16,9 +16,8 @@ */ /** * @file include/taler/taler-merchant/post-private-orders.h - * @brief C interface for POST /private/orders of the merchant backend + * @brief C interface for the POST /private/orders endpoint * @author Christian Grothoff - * @author Marcello Stanisci */ #ifndef _TALER_MERCHANT__POST_PRIVATE_ORDERS_H #define _TALER_MERCHANT__POST_PRIVATE_ORDERS_H @@ -27,45 +26,164 @@ /** - * Handle for a POST /private/orders request. + * A product from inventory to include in an order. */ -struct TALER_MERCHANT_PostOrdersHandle; +struct TALER_MERCHANT_PostPrivateOrdersInventoryProduct +{ + + /** + * Identifier of the product. + */ + const char *product_id; + + /** + * Quantity of the product to include. + */ + uint32_t quantity; + + /** + * Fractional part of the quantity. + */ + uint32_t quantity_frac; + + /** + * Whether to use fractional quantity. + */ + bool use_fractional_quantity; + +}; /** - * One inventory product entry for POST /orders. + * Possible options for the POST /private/orders request. */ -struct TALER_MERCHANT_InventoryProduct +enum TALER_MERCHANT_PostPrivateOrdersOption { + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_END = 0, /** - * Identifier of the product in the inventory. + * Refund delay. */ - const char *product_id; + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY, /** - * How many units of this product should be ordered. + * Payment target (type of payment method). */ - uint64_t quantity; + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET, /** - * Fractional component of the quantity in units of 1/1000000 of the - * base value. + * Session identifier for session-bound payments. */ - uint32_t quantity_frac; + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID, /** - * Set to true if this product uses fractional quantity fields. + * Whether to create a claim token. */ - bool use_fractional_quantity; + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN, + + /** + * OTP device ID. + */ + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID, + + /** + * Inventory products to include in the order. + */ + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS, + + /** + * Lock UUIDs for inventory locks. + */ + TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS + +}; + + +/** + * Value for an option for the POST /private/orders request. + */ +struct TALER_MERCHANT_PostPrivateOrdersOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateOrdersOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY. + */ + struct GNUNET_TIME_Relative refund_delay; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET. + */ + const char *payment_target; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID. + */ + const char *session_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN. + */ + bool create_token; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID. + */ + const char *otp_id; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS. + */ + struct + { + unsigned int num; + const struct TALER_MERCHANT_PostPrivateOrdersInventoryProduct *products; + } inventory_products; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS. + */ + struct + { + unsigned int num; + const char **uuids; + } lock_uuids; + + } details; }; /** + * Handle for a POST /private/orders request. + */ +struct TALER_MERCHANT_PostPrivateOrdersHandle; + + +/** * Response details for a POST /private/orders request. */ -struct TALER_MERCHANT_PostOrdersReply +struct TALER_MERCHANT_PostPrivateOrdersResponse { /** @@ -86,17 +204,17 @@ struct TALER_MERCHANT_PostOrdersReply { /** - * The assigned order identifier. + * Identifier of the created order. */ const char *order_id; /** - * Claim token for the order, or NULL if none was issued. + * Claim token, or NULL. */ const struct TALER_ClaimTokenP *token; /** - * Deadline by which the wallet must pay (may be zero for old backends). + * Payment deadline. */ struct GNUNET_TIME_Timestamp pay_deadline; @@ -109,32 +227,32 @@ struct TALER_MERCHANT_PostOrdersReply { /** - * Identifier of the product that ran out of stock. + * Product that is out of stock. */ const char *product_id; /** - * Quantity that was requested. + * Requested quantity (integer part). */ uint64_t requested_quantity; /** - * Fractional part of the requested quantity. + * Requested quantity (fractional part). */ uint32_t requested_quantity_frac; /** - * Quantity that is available. + * Available quantity (integer part). */ uint64_t available_quantity; /** - * Fractional part of the available quantity. + * Available quantity (fractional part). */ uint32_t available_quantity_frac; /** - * When restocking is expected (may be zero/unset). + * Expected restock time. */ struct GNUNET_TIME_Timestamp restock_expected; @@ -146,113 +264,209 @@ struct TALER_MERCHANT_PostOrdersReply /** - * Callback for a POST /private/orders request. + * Terminate the list of the options. * - * @param cls closure - * @param por response details + * @return the terminating object */ -typedef void -(*TALER_MERCHANT_PostOrdersCallback)( - void *cls, - const struct TALER_MERCHANT_PostOrdersReply *por); +#define TALER_MERCHANT_post_private_orders_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_END \ + } +/** + * Set refund delay. + * + * @param d refund delay + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_orders_option_refund_delay(d) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY, \ + .details.refund_delay = (d) \ + } /** - * Issue a POST /private/orders request (simple form). + * Set payment target. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order JSON object describing the order - * @param refund_delay refund delay for this order - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @param t payment target string + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_orders_option_payment_target(t) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET, \ + .details.payment_target = (t) \ + } + +/** + * Set session identifier. + * + * @param s session ID + * @return representation of the option */ -struct TALER_MERCHANT_PostOrdersHandle * -TALER_MERCHANT_orders_post (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const json_t *order, - struct GNUNET_TIME_Relative refund_delay, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls); +#define TALER_MERCHANT_post_private_orders_option_session_id(s) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID, \ + .details.session_id = (s) \ + } +/** + * Set whether to create a claim token. + * + * @param c true to create token + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_orders_option_create_token(c) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN, \ + .details.create_token = (c) \ + } /** - * Issue a POST /private/orders request with extended options. + * Set OTP device ID. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order JSON object describing the order - * @param refund_delay refund delay for this order - * @param payment_target desired payment target, or NULL for default - * @param inventory_products_length number of entries in @a inventory_products - * @param inventory_products array of inventory products to lock - * @param uuids_length number of entries in @a uuids - * @param uuids array of idempotency UUIDs - * @param create_token whether to create a claim token - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @param o OTP device ID + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_orders_option_otp_id(o) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID, \ + .details.otp_id = (o) \ + } + +/** + * Set inventory products. + * + * @param n number of products + * @param p array of inventory products + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_orders_option_inventory_products(n,p) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS \ + , \ + .details.inventory_products = { .num = (n), .products = (p) } \ + } + +/** + * Set lock UUIDs. + * + * @param n number of UUIDs + * @param u array of UUID strings + * @return representation of the option */ -struct TALER_MERCHANT_PostOrdersHandle * -TALER_MERCHANT_orders_post2 ( +#define TALER_MERCHANT_post_private_orders_option_lock_uuids(n,u) \ + (const struct TALER_MERCHANT_PostPrivateOrdersOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS, \ + .details.lock_uuids = { .num = (n), .uuids = (u) } \ + } + + +/** + * Set the requested options for the operation. + * + * @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_orders_set_options_ ( + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateOrdersOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param ppoh 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_orders_set_options(ppoh,...) \ + TALER_MERCHANT_post_private_orders_set_options_ ( \ + ppoh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateOrdersOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_orders_option_end_ () } \ + )) + + +/** + * Set up POST /private/orders operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param order order contract (JSON) + * @return handle to operation + */ +struct TALER_MERCHANT_PostPrivateOrdersHandle * +TALER_MERCHANT_post_private_orders_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const json_t *order, - struct GNUNET_TIME_Relative refund_delay, - const char *payment_target, - unsigned int inventory_products_length, - const struct TALER_MERCHANT_InventoryProduct inventory_products[], - unsigned int uuids_length, - const char *uuids[], - bool create_token, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls); + const char *url, + const json_t *order); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateOrdersCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/orders request. + * + * @param cls closure + * @param por response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateOrdersCallback)( + TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateOrdersResponse *por); /** - * Issue a POST /private/orders request with all options. + * Start POST /private/orders operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param order JSON object describing the order - * @param session_id session identifier, or NULL - * @param refund_delay refund delay for this order - * @param payment_target desired payment target, or NULL for default - * @param inventory_products_length number of entries in @a inventory_products - * @param inventory_products array of inventory products to lock - * @param uuids_length number of entries in @a uuids - * @param uuids array of idempotency UUIDs - * @param create_token whether to create a claim token - * @param cb callback to invoke with the result + * @param[in,out] ppoh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_PostOrdersHandle * -TALER_MERCHANT_orders_post3 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const json_t *order, - const char *session_id, - struct GNUNET_TIME_Relative refund_delay, - const char *payment_target, - unsigned int inventory_products_length, - const struct TALER_MERCHANT_InventoryProduct inventory_products[], - unsigned int uuids_length, - const char *uuids[], - bool create_token, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_orders_start ( + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, + TALER_MERCHANT_PostPrivateOrdersCallback cb, + TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/orders request. + * Cancel POST /private/orders operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateOrdersCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] po handle to cancel + * @param[in] ppoh operation to cancel */ void -TALER_MERCHANT_orders_post_cancel ( - struct TALER_MERCHANT_PostOrdersHandle *po); +TALER_MERCHANT_post_private_orders_cancel ( + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_ORDERS_H */ diff --git a/src/include/taler/taler-merchant/post-private-otp-devices-new.h b/src/include/taler/taler-merchant/post-private-otp-devices-new.h @@ -1,121 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-otp-devices-new.h - * @brief C interface for the POST /private/otp-devices endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_OTP_DEVICES_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_OTP_DEVICES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /private/otp-devices request. - */ -struct TALER_MERCHANT_PostPrivateOtpDevicesHandle; - - -/** - * Response details for a POST /private/otp-devices request. - */ -struct TALER_MERCHANT_PostPrivateOtpDevicesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Set up POST /private/otp-devices operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param otp_device_id identifier for the new OTP device - * @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 * -TALER_MERCHANT_post_private_otp_devices_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id, - const char *otp_device_description, - const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm otp_algorithm, - uint64_t otp_ctr); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateOtpDevicesCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/otp-devices request. - * - * @param cls closure - * @param odr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateOtpDevicesCallback)( - TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateOtpDevicesResponse *odr); - - -/** - * Start POST /private/otp-devices operation. - * - * @param[in,out] ppoh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_otp_devices_start ( - struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, - TALER_MERCHANT_PostPrivateOtpDevicesCallback cb, - TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/otp-devices operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateOtpDevicesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppoh operation to cancel - */ -void -TALER_MERCHANT_post_private_otp_devices_cancel ( - struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_OTP_DEVICES_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-otp-devices.h b/src/include/taler/taler-merchant/post-private-otp-devices.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-otp-devices.h - * @brief C interface for POST /private/otp-devices of the merchant backend + * @brief C interface for the POST /private/otp-devices endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_OTP_DEVICES_H @@ -28,56 +28,94 @@ /** * Handle for a POST /private/otp-devices request. */ -struct TALER_MERCHANT_OtpDevicesPostHandle; +struct TALER_MERCHANT_PostPrivateOtpDevicesHandle; /** - * Callback for a POST /private/otp-devices request. - * - * @param cls closure - * @param hr HTTP response details + * Response details for a POST /private/otp-devices request. */ -typedef void -(*TALER_MERCHANT_OtpDevicesPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +struct TALER_MERCHANT_PostPrivateOtpDevicesResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; /** - * Issue a POST /private/otp-devices request to register a new OTP device. + * Set up POST /private/otp-devices operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param otp_device_id identifier for the new OTP device * @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) - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_OtpDevicesPostHandle * -TALER_MERCHANT_otp_devices_post ( +struct TALER_MERCHANT_PostPrivateOtpDevicesHandle * +TALER_MERCHANT_post_private_otp_devices_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *otp_device_id, const char *otp_device_description, const char *otp_key, enum TALER_MerchantConfirmationAlgorithm otp_algorithm, - uint64_t otp_ctr, - TALER_MERCHANT_OtpDevicesPostCallback cb, - void *cb_cls); + uint64_t otp_ctr); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateOtpDevicesCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/otp-devices request. + * + * @param cls closure + * @param odr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateOtpDevicesCallback)( + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateOtpDevicesResponse *odr); + + +/** + * Start POST /private/otp-devices operation. + * + * @param[in,out] ppoh operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_private_otp_devices_start ( + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, + TALER_MERCHANT_PostPrivateOtpDevicesCallback cb, + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/otp-devices request. + * Cancel POST /private/otp-devices operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateOtpDevicesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tph handle to cancel + * @param[in] ppoh operation to cancel */ void -TALER_MERCHANT_otp_devices_post_cancel ( - struct TALER_MERCHANT_OtpDevicesPostHandle *tph); +TALER_MERCHANT_post_private_otp_devices_cancel ( + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_OTP_DEVICES_H */ diff --git a/src/include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h b/src/include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h @@ -1,251 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h - * @brief C interface for the POST /private/products/$PRODUCT_ID/lock endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_PRODUCT_ID_LOCK_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_PRODUCT_ID_LOCK_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/products/$PRODUCT_ID/lock request. - */ -enum TALER_MERCHANT_PostPrivateProductsLockOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_END = 0, - - /** - * Fractional part of the quantity to lock. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC, - - /** - * Whether to use fractional quantity. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY - -}; - - -/** - * Value for an option for the POST /private/products/$PRODUCT_ID/lock request. - */ -struct TALER_MERCHANT_PostPrivateProductsLockOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateProductsLockOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC. - */ - uint32_t quantity_frac; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY. - */ - bool use_fractional_quantity; - - } details; - -}; - - -/** - * Handle for a POST /private/products/$PRODUCT_ID/lock request. - */ -struct TALER_MERCHANT_PostPrivateProductsLockHandle; - - -/** - * Response details for a POST /private/products/$PRODUCT_ID/lock request. - */ -struct TALER_MERCHANT_PostPrivateProductsLockResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_products_lock_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_END \ - } - -/** - * Set fractional part of quantity. - * - * @param f fractional part - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_lock_option_quantity_frac(f) \ - (const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC, \ - .details.quantity_frac = (f) \ - } - -/** - * Set to use fractional quantity. - * - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_lock_option_use_frac_quantity() \ - (const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY, \ - .details.use_fractional_quantity = true \ - } - - -/** - * Set the requested options for the operation. - * - * @param pplh 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_products_lock_set_options_ ( - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param pplh 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_products_lock_set_options(pplh,...) \ - TALER_MERCHANT_post_private_products_lock_set_options_ ( \ - pplh, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_products_lock_option_end_ \ - () } \ - )) - - -/** - * Set up POST /private/products/$PRODUCT_ID/lock operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param product_id identifier of the product to lock - * @param uuid idempotency UUID for this lock operation - * @param duration how long to lock the inventory - * @param quantity number of units to lock - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateProductsLockHandle * -TALER_MERCHANT_post_private_products_lock_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id, - const char *uuid, - struct GNUNET_TIME_Relative duration, - uint64_t quantity); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateProductsLockCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/products/$PRODUCT_ID/lock request. - * - * @param cls closure - * @param plr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateProductsLockCallback)( - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateProductsLockResponse *plr); - - -/** - * Start POST /private/products/$PRODUCT_ID/lock operation. - * - * @param[in,out] pplh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_products_lock_start ( - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, - TALER_MERCHANT_PostPrivateProductsLockCallback cb, - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/products/$PRODUCT_ID/lock operation. This function - * must not be called by clients after the - * TALER_MERCHANT_PostPrivateProductsLockCallback has been invoked (as in - * those cases it'll be called internally by the implementation already). - * - * @param[in] pplh operation to cancel - */ -void -TALER_MERCHANT_post_private_products_lock_cancel ( - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_PRODUCT_ID_LOCK_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h b/src/include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h - * @brief C interface for POST /private/products/$PRODUCT_ID/lock of the merchant backend + * @brief C interface for the POST /private/products/$PRODUCT_ID/lock endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_PRODUCT_ID_LOCK_H @@ -26,85 +26,226 @@ /** + * Possible options for the POST /private/products/$PRODUCT_ID/lock request. + */ +enum TALER_MERCHANT_PostPrivateProductsLockOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_END = 0, + + /** + * Fractional part of the quantity to lock. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC, + + /** + * Whether to use fractional quantity. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY + +}; + + +/** + * Value for an option for the POST /private/products/$PRODUCT_ID/lock request. + */ +struct TALER_MERCHANT_PostPrivateProductsLockOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateProductsLockOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC. + */ + uint32_t quantity_frac; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY. + */ + bool use_fractional_quantity; + + } details; + +}; + + +/** * Handle for a POST /private/products/$PRODUCT_ID/lock request. */ -struct TALER_MERCHANT_ProductLockHandle; +struct TALER_MERCHANT_PostPrivateProductsLockHandle; /** - * Callback for a POST /private/products/$PRODUCT_ID/lock request. + * Response details for a POST /private/products/$PRODUCT_ID/lock request. + */ +struct TALER_MERCHANT_PostPrivateProductsLockResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. * - * @param cls closure - * @param hr HTTP response details + * @return the terminating object */ -typedef void -(*TALER_MERCHANT_ProductLockCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +#define TALER_MERCHANT_post_private_products_lock_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_END \ + } +/** + * Set fractional part of quantity. + * + * @param f fractional part + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_lock_option_quantity_frac(f) \ + (const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC, \ + .details.quantity_frac = (f) \ + } /** - * Issue a POST /private/products/$PRODUCT_ID/lock request (simple form, - * integer quantities only). + * Set to use fractional quantity. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_lock_option_use_frac_quantity() \ + (const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY, \ + .details.use_fractional_quantity = true \ + } + + +/** + * Set the requested options for the operation. + * + * @param pplh 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_products_lock_set_options_ ( + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param pplh 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_products_lock_set_options(pplh,...) \ + TALER_MERCHANT_post_private_products_lock_set_options_ ( \ + pplh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_products_lock_option_end_ \ + () } \ + )) + + +/** + * Set up POST /private/products/$PRODUCT_ID/lock operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend * @param product_id identifier of the product to lock * @param uuid idempotency UUID for this lock operation * @param duration how long to lock the inventory * @param quantity number of units to lock - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_ProductLockHandle * -TALER_MERCHANT_product_lock (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - const char *uuid, - struct GNUNET_TIME_Relative duration, - uint32_t quantity, - TALER_MERCHANT_ProductLockCallback cb, - void *cb_cls); +struct TALER_MERCHANT_PostPrivateProductsLockHandle * +TALER_MERCHANT_post_private_products_lock_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *product_id, + const char *uuid, + struct GNUNET_TIME_Relative duration, + uint64_t quantity); +#ifndef TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE /** - * Issue a POST /private/products/$PRODUCT_ID/lock request with fractional - * quantity support. + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateProductsLockCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/products/$PRODUCT_ID/lock request. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param product_id identifier of the product to lock - * @param uuid idempotency UUID for this lock operation - * @param duration how long to lock the inventory - * @param quantity integer part of the quantity to lock - * @param quantity_frac fractional part of the quantity - * @param use_fractional_quantity if true, use fractional quantity - * @param cb callback to invoke with the result + * @param cls closure + * @param plr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateProductsLockCallback)( + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateProductsLockResponse *plr); + + +/** + * Start POST /private/products/$PRODUCT_ID/lock operation. + * + * @param[in,out] pplh operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductLockHandle * -TALER_MERCHANT_product_lock2 (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - const char *uuid, - struct GNUNET_TIME_Relative duration, - uint64_t quantity, - uint32_t quantity_frac, - bool use_fractional_quantity, - TALER_MERCHANT_ProductLockCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_products_lock_start ( + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, + TALER_MERCHANT_PostPrivateProductsLockCallback cb, + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/products/$PRODUCT_ID/lock request. + * Cancel POST /private/products/$PRODUCT_ID/lock operation. This function + * must not be called by clients after the + * TALER_MERCHANT_PostPrivateProductsLockCallback has been invoked (as in + * those cases it'll be called internally by the implementation already). * - * @param[in] plh handle to cancel + * @param[in] pplh operation to cancel */ void -TALER_MERCHANT_product_lock_cancel ( - struct TALER_MERCHANT_ProductLockHandle *plh); +TALER_MERCHANT_post_private_products_lock_cancel ( + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_PRODUCT_ID_LOCK_H */ diff --git a/src/include/taler/taler-merchant/post-private-products-new.h b/src/include/taler/taler-merchant/post-private-products-new.h @@ -1,459 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-products-new.h - * @brief C interface for the POST /private/products endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/products request. - */ -enum TALER_MERCHANT_PostPrivateProductsOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_END = 0, - - /** - * Internationalized descriptions (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N, - - /** - * Tax information (JSON array). - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES, - - /** - * Storage location (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS, - - /** - * Expected restock time. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK, - - /** - * Minimum age requirement. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE, - - /** - * Category IDs. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES, - - /** - * Additional unit prices. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES, - - /** - * Fractional part of total stock. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC, - - /** - * Whether fractional quantities are allowed. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_ALLOW_FRACTION, - - /** - * Precision level for fractions. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL - -}; - - -/** - * Value for an option for the POST /private/products request. - */ -struct TALER_MERCHANT_PostPrivateProductsOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateProductsOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N. - */ - const json_t *description_i18n; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES. - */ - const json_t *taxes; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS. - */ - const json_t *address; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK. - */ - struct GNUNET_TIME_Timestamp next_restock; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE. - */ - uint32_t minimum_age; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES. - */ - struct - { - unsigned int num; - const uint64_t *cats; - } categories; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES. - */ - 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_UNIT_ALLOW_FRACTION. - */ - bool unit_allow_fraction; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL. - */ - uint32_t unit_precision_level; - - } details; - -}; - - -/** - * Handle for a POST /private/products request. - */ -struct TALER_MERCHANT_PostPrivateProductsHandle; - - -/** - * Response details for a POST /private/products request. - */ -struct TALER_MERCHANT_PostPrivateProductsResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object of struct TALER_MERCHANT_PostPrivateProductsOptionValue - */ -#define TALER_MERCHANT_post_private_products_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_END \ - } - -/** - * Set internationalized descriptions. - * - * @param d descriptions JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_description_i18n(d) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N \ - , \ - .details.description_i18n = (d) \ - } - -/** - * Set tax information. - * - * @param t taxes JSON array - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_taxes(t) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES, \ - .details.taxes = (t) \ - } - -/** - * Set storage address. - * - * @param a address JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_address(a) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS, \ - .details.address = (a) \ - } - -/** - * Set expected restock time. - * - * @param r restock timestamp - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_next_restock(r) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK, \ - .details.next_restock = (r) \ - } - -/** - * Set minimum age requirement. - * - * @param a minimum age (0 for none) - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_minimum_age(a) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE, \ - .details.minimum_age = (a) \ - } - -/** - * Set category IDs. - * - * @param n number of categories - * @param c array of category IDs - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_categories(n,c) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES, \ - .details.categories = { .num = (n), .cats = (c) } \ - } - -/** - * Set additional unit prices. - * - * @param p array of unit prices - * @param l number of prices - * @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) } \ - } - -/** - * Set fractional part of total stock. - * - * @param f fractional part - * @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) \ - } - -/** - * Set whether fractional quantities are allowed. - * - * @param b true to allow fractions - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_unit_allow_fraction(b) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_ALLOW_FRACTION, \ - .details.unit_allow_fraction = (b) \ - } - -/** - * Set precision level for fractional quantities. - * - * @param p precision level - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_products_option_unit_precision_level(p) \ - (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL, \ - .details.unit_precision_level = (p) \ - } - - -/** - * Set the requested options for the operation. - * - * @param ppph 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_products_set_options_ ( - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateProductsOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ppph 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_products_set_options(ppph,...) \ - TALER_MERCHANT_post_private_products_set_options_ ( \ - ppph, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateProductsOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_products_option_end_ () } \ - )) - - -/** - * Set up POST /private/products operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param product_id identifier for the new product - * @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) - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateProductsHandle * -TALER_MERCHANT_post_private_products_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id, - const char *description, - const char *unit, - const struct TALER_Amount *price, - const char *image, - int64_t total_stock); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateProductsCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/products request. - * - * @param cls closure - * @param ppr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateProductsCallback)( - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateProductsResponse *ppr); - - -/** - * Start POST /private/products operation. - * - * @param[in,out] ppph operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_products_start ( - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, - TALER_MERCHANT_PostPrivateProductsCallback cb, - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/products operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateProductsCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppph operation to cancel - */ -void -TALER_MERCHANT_post_private_products_cancel ( - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-products.h b/src/include/taler/taler-merchant/post-private-products.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-products.h - * @brief C interface for POST /private/products of the merchant backend + * @brief C interface for the POST /private/products endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_H @@ -26,201 +26,434 @@ /** + * Possible options for the POST /private/products request. + */ +enum TALER_MERCHANT_PostPrivateProductsOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_END = 0, + + /** + * Internationalized descriptions (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N, + + /** + * Tax information (JSON array). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES, + + /** + * Storage location (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS, + + /** + * Expected restock time. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK, + + /** + * Minimum age requirement. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE, + + /** + * Category IDs. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES, + + /** + * Additional unit prices. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES, + + /** + * Fractional part of total stock. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC, + + /** + * Whether fractional quantities are allowed. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_ALLOW_FRACTION, + + /** + * Precision level for fractions. + */ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL + +}; + + +/** + * Value for an option for the POST /private/products request. + */ +struct TALER_MERCHANT_PostPrivateProductsOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateProductsOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N. + */ + const json_t *description_i18n; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES. + */ + const json_t *taxes; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS. + */ + const json_t *address; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK. + */ + struct GNUNET_TIME_Timestamp next_restock; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE. + */ + uint32_t minimum_age; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES. + */ + struct + { + unsigned int num; + const uint64_t *cats; + } categories; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRICES. + */ + 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_UNIT_ALLOW_FRACTION. + */ + bool unit_allow_fraction; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL. + */ + uint32_t unit_precision_level; + + } details; + +}; + + +/** * Handle for a POST /private/products request. */ -struct TALER_MERCHANT_ProductsPostHandle; +struct TALER_MERCHANT_PostPrivateProductsHandle; /** - * Callback for a POST /private/products request. + * Response details for a POST /private/products request. + */ +struct TALER_MERCHANT_PostPrivateProductsResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. * - * @param cls closure - * @param hr HTTP response details + * @return the terminating object of struct TALER_MERCHANT_PostPrivateProductsOptionValue */ -typedef void -(*TALER_MERCHANT_ProductsPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +#define TALER_MERCHANT_post_private_products_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_END \ + } +/** + * Set internationalized descriptions. + * + * @param d descriptions JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_description_i18n(d) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_DESCRIPTION_I18N \ + , \ + .details.description_i18n = (d) \ + } /** - * Issue a POST /private/products request (simple form). + * Set tax information. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param product_id identifier for the new product - * @param description human-readable product description - * @param description_i18n internationalized descriptions (JSON), or NULL - * @param unit unit of measurement - * @param price unit price - * @param image base64-encoded image, or empty string - * @param taxes tax information (JSON array), or NULL - * @param total_stock total stock (-1 for unlimited) - * @param address storage location (JSON), or NULL - * @param next_restock expected restock time - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @param t taxes JSON array + * @return representation of the option */ -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_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, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls); +#define TALER_MERCHANT_post_private_products_option_taxes(t) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES, \ + .details.taxes = (t) \ + } +/** + * Set storage address. + * + * @param a address JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_address(a) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS, \ + .details.address = (a) \ + } /** - * Issue a POST /private/products request with minimum age. + * Set expected restock time. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param product_id identifier for the new product - * @param description human-readable product description - * @param description_i18n internationalized descriptions (JSON), or NULL - * @param unit unit of measurement - * @param price unit price - * @param image base64-encoded image, or empty string - * @param taxes tax information (JSON array), or NULL - * @param total_stock total stock (-1 for unlimited) - * @param address storage location (JSON), or NULL - * @param next_restock expected restock time - * @param minimum_age minimum age requirement (0 for none) - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @param r restock timestamp + * @return representation of the option */ -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_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, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - uint32_t minimum_age, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls); +#define TALER_MERCHANT_post_private_products_option_next_restock(r) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK, \ + .details.next_restock = (r) \ + } + +/** + * Set minimum age requirement. + * + * @param a minimum age (0 for none) + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_minimum_age(a) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE, \ + .details.minimum_age = (a) \ + } + +/** + * Set category IDs. + * + * @param n number of categories + * @param c array of category IDs + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_categories(n,c) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_CATEGORIES, \ + .details.categories = { .num = (n), .cats = (c) } \ + } + +/** + * Set additional unit prices. + * + * @param p array of unit prices + * @param l number of prices + * @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) } \ + } + +/** + * Set fractional part of total stock. + * + * @param f fractional part + * @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) \ + } + +/** + * Set whether fractional quantities are allowed. + * + * @param b true to allow fractions + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_unit_allow_fraction(b) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_ALLOW_FRACTION, \ + .details.unit_allow_fraction = (b) \ + } + +/** + * Set precision level for fractional quantities. + * + * @param p precision level + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_products_option_unit_precision_level(p) \ + (const struct TALER_MERCHANT_PostPrivateProductsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_UNIT_PRECISION_LEVEL, \ + .details.unit_precision_level = (p) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ppph 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_products_set_options_ ( + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateProductsOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param ppph 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_products_set_options(ppph,...) \ + TALER_MERCHANT_post_private_products_set_options_ ( \ + ppph, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateProductsOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_products_option_end_ () } \ + )) /** - * Issue a POST /private/products request with category support. + * Set up POST /private/products operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param product_id identifier for the new product * @param description human-readable product description - * @param description_i18n internationalized descriptions (JSON), or NULL * @param unit unit of measurement * @param price unit price * @param image base64-encoded image, or empty string - * @param taxes tax information (JSON array), or NULL * @param total_stock total stock (-1 for unlimited) - * @param address storage location (JSON), or NULL - * @param next_restock expected restock time - * @param minimum_age minimum age requirement (0 for none) - * @param num_cats number of category IDs in @a cats - * @param cats array of category IDs - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post3 ( +struct TALER_MERCHANT_PostPrivateProductsHandle * +TALER_MERCHANT_post_private_products_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + 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, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - uint32_t minimum_age, - unsigned int num_cats, - const uint64_t *cats, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls); + int64_t total_stock); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateProductsCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/products request. + * + * @param cls closure + * @param ppr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateProductsCallback)( + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateProductsResponse *ppr); /** - * Issue a POST /private/products request with full unit/fraction support. + * Start POST /private/products operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param product_id identifier for the new product - * @param description human-readable product description - * @param description_i18n internationalized descriptions (JSON), or NULL - * @param unit unit of measurement - * @param unit_prices array of unit prices (for different payment options) - * @param unit_price_len number of prices in @a unit_prices - * @param image base64-encoded image, or empty string - * @param taxes tax information (JSON array), or NULL - * @param total_stock integer part of total stock (-1 for unlimited) - * @param total_stock_frac fractional part of total stock - * @param unit_allow_fraction whether fractional quantities are allowed - * @param unit_precision_level precision level for fractions, or NULL - * @param address storage location (JSON), or NULL - * @param next_restock expected restock time - * @param minimum_age minimum age requirement (0 for none) - * @param num_cats number of category IDs in @a cats - * @param cats array of category IDs - * @param cb callback to invoke with the result + * @param[in,out] ppph operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post4 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - const char *description, - const json_t *description_i18n, - const char *unit, - const struct TALER_Amount *unit_prices, - size_t unit_price_len, - const char *image, - const json_t *taxes, - int64_t total_stock, - uint32_t total_stock_frac, - bool unit_allow_fraction, - const uint32_t *unit_precision_level, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - uint32_t minimum_age, - unsigned int num_cats, - const uint64_t *cats, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_products_start ( + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, + TALER_MERCHANT_PostPrivateProductsCallback cb, + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/products request. + * Cancel POST /private/products operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateProductsCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] pph handle to cancel + * @param[in] ppph operation to cancel */ void -TALER_MERCHANT_products_post_cancel ( - struct TALER_MERCHANT_ProductsPostHandle *pph); +TALER_MERCHANT_post_private_products_cancel ( + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_PRODUCTS_H */ diff --git a/src/include/taler/taler-merchant/post-private-templates-new.h b/src/include/taler/taler-merchant/post-private-templates-new.h @@ -1,223 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-templates-new.h - * @brief C interface for the POST /private/templates endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_TEMPLATES_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_TEMPLATES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/templates request. - */ -enum TALER_MERCHANT_PostPrivateTemplatesOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_END = 0, - - /** - * OTP device ID to associate with the template. - */ - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID - -}; - - -/** - * Value for an option for the POST /private/templates request. - */ -struct TALER_MERCHANT_PostPrivateTemplatesOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateTemplatesOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID. - */ - const char *otp_id; - - } details; - -}; - - -/** - * Handle for a POST /private/templates request. - */ -struct TALER_MERCHANT_PostPrivateTemplatesHandle; - - -/** - * Response details for a POST /private/templates request. - */ -struct TALER_MERCHANT_PostPrivateTemplatesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_templates_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_END \ - } - -/** - * Set OTP device ID. - * - * @param o OTP device ID - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_templates_option_otp_id(o) \ - (const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID, \ - .details.otp_id = (o) \ - } - - -/** - * 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_templates_set_options_ ( - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue *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_templates_set_options(ppth,...) \ - TALER_MERCHANT_post_private_templates_set_options_ ( \ - ppth, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_templates_option_end_ () } \ - )) - - -/** - * Set up POST /private/templates operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param template_id identifier for the new template - * @param template_description human-readable description - * @param template_contract template contract (JSON) - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateTemplatesHandle * -TALER_MERCHANT_post_private_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id, - const char *template_description, - const json_t *template_contract); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateTemplatesCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/templates request. - * - * @param cls closure - * @param ptr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateTemplatesCallback)( - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateTemplatesResponse *ptr); - - -/** - * Start POST /private/templates operation. - * - * @param[in,out] ppth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_templates_start ( - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, - TALER_MERCHANT_PostPrivateTemplatesCallback cb, - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/templates operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateTemplatesCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppth operation to cancel - */ -void -TALER_MERCHANT_post_private_templates_cancel ( - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_TEMPLATES_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-templates.h b/src/include/taler/taler-merchant/post-private-templates.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-templates.h - * @brief C interface for POST /private/templates of the merchant backend + * @brief C interface for the POST /private/templates endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_TEMPLATES_H @@ -26,56 +26,198 @@ /** + * Possible options for the POST /private/templates request. + */ +enum TALER_MERCHANT_PostPrivateTemplatesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_END = 0, + + /** + * OTP device ID to associate with the template. + */ + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID + +}; + + +/** + * Value for an option for the POST /private/templates request. + */ +struct TALER_MERCHANT_PostPrivateTemplatesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateTemplatesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID. + */ + const char *otp_id; + + } details; + +}; + + +/** * Handle for a POST /private/templates request. */ -struct TALER_MERCHANT_TemplatesPostHandle; +struct TALER_MERCHANT_PostPrivateTemplatesHandle; /** - * Callback for a POST /private/templates request. + * Response details for a POST /private/templates request. + */ +struct TALER_MERCHANT_PostPrivateTemplatesResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. * - * @param cls closure - * @param hr HTTP response details + * @return the terminating object */ -typedef void -(*TALER_MERCHANT_TemplatesPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +#define TALER_MERCHANT_post_private_templates_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_END \ + } + +/** + * Set OTP device ID. + * + * @param o OTP device ID + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_templates_option_otp_id(o) \ + (const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID, \ + .details.otp_id = (o) \ + } /** - * Issue a POST /private/templates request to create a new template. + * Set the requested options for the operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @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_templates_set_options_ ( + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue *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_templates_set_options(ppth,...) \ + TALER_MERCHANT_post_private_templates_set_options_ ( \ + ppth, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_templates_option_end_ () } \ + )) + + +/** + * Set up POST /private/templates operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend * @param template_id identifier for the new template * @param template_description human-readable description - * @param otp_id OTP device ID to associate, or NULL * @param template_contract template contract (JSON) - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_TemplatesPostHandle * -TALER_MERCHANT_templates_post ( +struct TALER_MERCHANT_PostPrivateTemplatesHandle * +TALER_MERCHANT_post_private_templates_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *template_id, const char *template_description, - const char *otp_id, - const json_t *template_contract, - TALER_MERCHANT_TemplatesPostCallback cb, - void *cb_cls); + const json_t *template_contract); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateTemplatesCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/templates request. + * + * @param cls closure + * @param ptr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateTemplatesCallback)( + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateTemplatesResponse *ptr); + + +/** + * Start POST /private/templates operation. + * + * @param[in,out] ppth operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_private_templates_start ( + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, + TALER_MERCHANT_PostPrivateTemplatesCallback cb, + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/templates request. + * Cancel POST /private/templates operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateTemplatesCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] tph handle to cancel + * @param[in] ppth operation to cancel */ void -TALER_MERCHANT_templates_post_cancel ( - struct TALER_MERCHANT_TemplatesPostHandle *tph); +TALER_MERCHANT_post_private_templates_cancel ( + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_TEMPLATES_H */ diff --git a/src/include/taler/taler-merchant/post-private-token-new.h b/src/include/taler/taler-merchant/post-private-token-new.h @@ -1,119 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-token-new.h - * @brief C interface for the POST /private/token endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_TOKEN_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_TOKEN_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /private/token request. - */ -struct TALER_MERCHANT_PostPrivateTokenHandle; - - -/** - * Response details for a POST /private/token request. - */ -struct TALER_MERCHANT_PostPrivateTokenResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Set up POST /private/token operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @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 * -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); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateTokenCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/token request. - * - * @param cls closure - * @param ptr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateTokenCallback)( - TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateTokenResponse *ptr); - - -/** - * Start POST /private/token operation. - * - * @param[in,out] ppth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_token_start ( - struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, - TALER_MERCHANT_PostPrivateTokenCallback cb, - TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/token operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateTokenCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppth operation to cancel - */ -void -TALER_MERCHANT_post_private_token_cancel ( - struct TALER_MERCHANT_PostPrivateTokenHandle *ppth); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_TOKEN_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-token.h b/src/include/taler/taler-merchant/post-private-token.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-token.h - * @brief C interface for POST /private/token of the merchant backend + * @brief C interface for the POST /private/token endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_TOKEN_H @@ -28,54 +28,92 @@ /** * Handle for a POST /private/token request. */ -struct TALER_MERCHANT_InstanceTokenPostHandle; +struct TALER_MERCHANT_PostPrivateTokenHandle; /** - * Callback for a POST /private/token request. - * - * @param cls closure - * @param hr HTTP response details + * Response details for a POST /private/token request. */ -typedef void -(*TALER_MERCHANT_InstanceTokenPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +struct TALER_MERCHANT_PostPrivateTokenResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; /** - * Issue a POST /private/token request to obtain an access token. + * Set up POST /private/token operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @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 - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_InstanceTokenPostHandle * -TALER_MERCHANT_instance_token_post ( +struct TALER_MERCHANT_PostPrivateTokenHandle * +TALER_MERCHANT_post_private_token_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, const char *scope, struct GNUNET_TIME_Relative duration, - bool refreshable, - TALER_MERCHANT_InstanceTokenPostCallback cb, - void *cb_cls); + bool refreshable); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateTokenCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/token request. + * + * @param cls closure + * @param ptr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateTokenCallback)( + TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateTokenResponse *ptr); + + +/** + * Start POST /private/token operation. + * + * @param[in,out] ppth operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_private_token_start ( + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, + TALER_MERCHANT_PostPrivateTokenCallback cb, + TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/token request. + * Cancel POST /private/token operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateTokenCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] itph handle to cancel + * @param[in] ppth operation to cancel */ void -TALER_MERCHANT_instance_token_post_cancel ( - struct TALER_MERCHANT_InstanceTokenPostHandle *itph); +TALER_MERCHANT_post_private_token_cancel ( + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_TOKEN_H */ diff --git a/src/include/taler/taler-merchant/post-private-tokenfamilies-new.h b/src/include/taler/taler-merchant/post-private-tokenfamilies-new.h @@ -1,261 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-tokenfamilies-new.h - * @brief C interface for the POST /private/tokenfamilies endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_TOKENFAMILIES_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_TOKENFAMILIES_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/tokenfamilies request. - */ -enum TALER_MERCHANT_PostPrivateTokenfamiliesOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_END = 0, - - /** - * Internationalized descriptions (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N, - - /** - * Extra data (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA - -}; - - -/** - * Value for an option for the POST /private/tokenfamilies request. - */ -struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateTokenfamiliesOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N. - */ - const json_t *description_i18n; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA. - */ - const json_t *extra_data; - - } details; - -}; - - -/** - * Handle for a POST /private/tokenfamilies request. - */ -struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle; - - -/** - * Response details for a POST /private/tokenfamilies request. - */ -struct TALER_MERCHANT_PostPrivateTokenfamiliesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_tokenfamilies_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_END \ - } - -/** - * Set internationalized descriptions. - * - * @param d descriptions JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_tokenfamilies_option_description_i18n(d) \ - (const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N, \ - .details.description_i18n = (d) \ - } - -/** - * Set extra data. - * - * @param e extra data JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_tokenfamilies_option_extra_data(e) \ - (const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA, \ - .details.extra_data = (e) \ - } - - -/** - * Set the requested options for the operation. - * - * @param ptfh 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_tokenfamilies_set_options_ ( - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ptfh 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_tokenfamilies_set_options(ptfh,...) \ - TALER_MERCHANT_post_private_tokenfamilies_set_options_ ( \ - ptfh, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_tokenfamilies_option_end_ \ - () } \ - )) - - -/** - * Set up POST /private/tokenfamilies operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param slug URL-safe slug identifier for the new token family - * @param name human-readable name - * @param description human-readable description - * @param valid_after start of validity period - * @param valid_before end of validity period - * @param duration duration of individual token validity - * @param validity_granularity granularity for validity alignment - * @param start_offset offset from purchase to start of validity - * @param kind kind of token family ("subscription" or "discount") - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle * -TALER_MERCHANT_post_private_tokenfamilies_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *slug, - const char *name, - const char *description, - struct GNUNET_TIME_Timestamp valid_after, - struct GNUNET_TIME_Timestamp valid_before, - struct GNUNET_TIME_Relative duration, - struct GNUNET_TIME_Relative validity_granularity, - struct GNUNET_TIME_Relative start_offset, - const char *kind); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateTokenfamiliesCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/tokenfamilies request. - * - * @param cls closure - * @param tfr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateTokenfamiliesCallback)( - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateTokenfamiliesResponse *tfr); - - -/** - * Start POST /private/tokenfamilies operation. - * - * @param[in,out] ptfh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_tokenfamilies_start ( - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, - TALER_MERCHANT_PostPrivateTokenfamiliesCallback cb, - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/tokenfamilies operation. This function must not be - * called by clients after the - * TALER_MERCHANT_PostPrivateTokenfamiliesCallback has been invoked (as in - * those cases it'll be called internally by the implementation already). - * - * @param[in] ptfh operation to cancel - */ -void -TALER_MERCHANT_post_private_tokenfamilies_cancel ( - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_TOKENFAMILIES_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-tokenfamilies.h b/src/include/taler/taler-merchant/post-private-tokenfamilies.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-tokenfamilies.h - * @brief C interface for POST /private/tokenfamilies of the merchant backend + * @brief C interface for the POST /private/tokenfamilies endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_TOKENFAMILIES_H @@ -26,70 +26,236 @@ /** + * Possible options for the POST /private/tokenfamilies request. + */ +enum TALER_MERCHANT_PostPrivateTokenfamiliesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_END = 0, + + /** + * Internationalized descriptions (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N, + + /** + * Extra data (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA + +}; + + +/** + * Value for an option for the POST /private/tokenfamilies request. + */ +struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateTokenfamiliesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N. + */ + const json_t *description_i18n; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA. + */ + const json_t *extra_data; + + } details; + +}; + + +/** * Handle for a POST /private/tokenfamilies request. */ -struct TALER_MERCHANT_TokenFamiliesPostHandle; +struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle; /** - * Callback for a POST /private/tokenfamilies request. + * Response details for a POST /private/tokenfamilies request. + */ +struct TALER_MERCHANT_PostPrivateTokenfamiliesResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. * - * @param cls closure - * @param hr HTTP response details + * @return the terminating object */ -typedef void -(*TALER_MERCHANT_TokenFamiliesPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +#define TALER_MERCHANT_post_private_tokenfamilies_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_END \ + } + +/** + * Set internationalized descriptions. + * + * @param d descriptions JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_tokenfamilies_option_description_i18n(d) \ + (const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N, \ + .details.description_i18n = (d) \ + } + +/** + * Set extra data. + * + * @param e extra data JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_tokenfamilies_option_extra_data(e) \ + (const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA, \ + .details.extra_data = (e) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ptfh 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_tokenfamilies_set_options_ ( + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue *options); /** - * Issue a POST /private/tokenfamilies request to create a new token family. + * Set the requested options for the operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ptfh 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_tokenfamilies_set_options(ptfh,...) \ + TALER_MERCHANT_post_private_tokenfamilies_set_options_ ( \ + ptfh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_tokenfamilies_option_end_ \ + () } \ + )) + + +/** + * Set up POST /private/tokenfamilies operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend * @param slug URL-safe slug identifier for the new token family * @param name human-readable name * @param description human-readable description - * @param description_i18n internationalized descriptions (JSON), or NULL - * @param extra_data extra data (JSON), or NULL * @param valid_after start of validity period * @param valid_before end of validity period * @param duration duration of individual token validity * @param validity_granularity granularity for validity alignment * @param start_offset offset from purchase to start of validity * @param kind kind of token family ("subscription" or "discount") - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_TokenFamiliesPostHandle * -TALER_MERCHANT_token_families_post ( +struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle * +TALER_MERCHANT_post_private_tokenfamilies_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *slug, const char *name, const char *description, - const json_t *description_i18n, - const json_t *extra_data, struct GNUNET_TIME_Timestamp valid_after, struct GNUNET_TIME_Timestamp valid_before, struct GNUNET_TIME_Relative duration, struct GNUNET_TIME_Relative validity_granularity, struct GNUNET_TIME_Relative start_offset, - const char *kind, - TALER_MERCHANT_TokenFamiliesPostCallback cb, - void *cb_cls); + const char *kind); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateTokenfamiliesCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/tokenfamilies request. + * + * @param cls closure + * @param tfr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateTokenfamiliesCallback)( + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateTokenfamiliesResponse *tfr); + + +/** + * Start POST /private/tokenfamilies operation. + * + * @param[in,out] ptfh operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_private_tokenfamilies_start ( + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, + TALER_MERCHANT_PostPrivateTokenfamiliesCallback cb, + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/tokenfamilies request. + * Cancel POST /private/tokenfamilies operation. This function must not be + * called by clients after the + * TALER_MERCHANT_PostPrivateTokenfamiliesCallback has been invoked (as in + * those cases it'll be called internally by the implementation already). * - * @param[in] pph handle to cancel + * @param[in] ptfh operation to cancel */ void -TALER_MERCHANT_token_families_post_cancel ( - struct TALER_MERCHANT_TokenFamiliesPostHandle *pph); +TALER_MERCHANT_post_private_tokenfamilies_cancel ( + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_TOKENFAMILIES_H */ diff --git a/src/include/taler/taler-merchant/post-private-transfers-new.h b/src/include/taler/taler-merchant/post-private-transfers-new.h @@ -1,145 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-transfers-new.h - * @brief C interface for the POST /private/transfers endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_TRANSFERS_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_TRANSFERS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /private/transfers request. - */ -struct TALER_MERCHANT_PostPrivateTransfersHandle; - - -/** - * Response details for a POST /private/transfers request. - */ -struct TALER_MERCHANT_PostPrivateTransfersResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_BAD_GATEWAY (exchange returned an error). - */ - struct - { - - /** - * Error code returned by the exchange. - */ - enum TALER_ErrorCode exchange_ec; - - /** - * HTTP status code returned by the exchange. - */ - unsigned int exchange_http_status; - - } bad_gateway; - - } details; - -}; - - -/** - * Set up POST /private/transfers operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param credit_amount amount credited in this transfer - * @param wtid wire transfer identifier - * @param payto_uri payto URI of the merchant account that received the funds - * @param exchange_url base URL of the exchange that made the transfer - * @return handle to operation - */ -struct TALER_MERCHANT_PostPrivateTransfersHandle * -TALER_MERCHANT_post_private_transfers_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_Amount *credit_amount, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct TALER_FullPayto payto_uri, - const char *exchange_url); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateTransfersCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/transfers request. - * - * @param cls closure - * @param ptr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateTransfersCallback)( - TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateTransfersResponse *ptr); - - -/** - * Start POST /private/transfers operation. - * - * @param[in,out] ppth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_transfers_start ( - struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth, - TALER_MERCHANT_PostPrivateTransfersCallback cb, - TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/transfers operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateTransfersCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppth operation to cancel - */ -void -TALER_MERCHANT_post_private_transfers_cancel ( - struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_TRANSFERS_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-transfers.h b/src/include/taler/taler-merchant/post-private-transfers.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-transfers.h - * @brief C interface for POST /private/transfers of the merchant backend + * @brief C interface for the POST /private/transfers endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_TRANSFERS_H @@ -28,13 +28,13 @@ /** * Handle for a POST /private/transfers request. */ -struct TALER_MERCHANT_PostTransfersHandle; +struct TALER_MERCHANT_PostPrivateTransfersHandle; /** * Response details for a POST /private/transfers request. */ -struct TALER_MERCHANT_PostTransfersResponse +struct TALER_MERCHANT_PostPrivateTransfersResponse { /** @@ -72,51 +72,74 @@ struct TALER_MERCHANT_PostTransfersResponse /** + * Set up POST /private/transfers operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend + * @param credit_amount amount credited in this transfer + * @param wtid wire transfer identifier + * @param payto_uri payto URI of the merchant account that received the funds + * @param exchange_url base URL of the exchange that made the transfer + * @return handle to operation + */ +struct TALER_MERCHANT_PostPrivateTransfersHandle * +TALER_MERCHANT_post_private_transfers_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_Amount *credit_amount, + const struct TALER_WireTransferIdentifierRawP *wtid, + struct TALER_FullPayto payto_uri, + const char *exchange_url); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateTransfersCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE */ + +/** * Callback for a POST /private/transfers request. * * @param cls closure * @param ptr response details */ typedef void -(*TALER_MERCHANT_PostTransfersCallback)( - void *cls, - const struct TALER_MERCHANT_PostTransfersResponse *ptr); +(*TALER_MERCHANT_PostPrivateTransfersCallback)( + TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateTransfersResponse *ptr); /** - * Issue a POST /private/transfers request to inform the merchant about - * a wire transfer from an exchange. + * Start POST /private/transfers operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param credit_amount amount credited in this transfer - * @param wtid wire transfer identifier - * @param payto_uri payto URI of the merchant account that received the funds - * @param exchange_url base URL of the exchange that made the transfer - * @param cb callback to invoke with the result + * @param[in,out] ppth operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_PostTransfersHandle * -TALER_MERCHANT_transfers_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_Amount *credit_amount, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct TALER_FullPayto payto_uri, - const char *exchange_url, - TALER_MERCHANT_PostTransfersCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_private_transfers_start ( + struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth, + TALER_MERCHANT_PostPrivateTransfersCallback cb, + TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/transfers request. + * Cancel POST /private/transfers operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateTransfersCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] pth handle to cancel + * @param[in] ppth operation to cancel */ void -TALER_MERCHANT_transfers_post_cancel ( - struct TALER_MERCHANT_PostTransfersHandle *pth); +TALER_MERCHANT_post_private_transfers_cancel ( + struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_TRANSFERS_H */ diff --git a/src/include/taler/taler-merchant/post-private-units-new.h b/src/include/taler/taler-merchant/post-private-units-new.h @@ -1,255 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-units-new.h - * @brief C interface for the POST /private/units endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_UNITS_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_UNITS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /private/units request. - */ -enum TALER_MERCHANT_PostPrivateUnitsOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_END = 0, - - /** - * Internationalized long names (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N, - - /** - * Internationalized short names (JSON). - */ - TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N - -}; - - -/** - * Value for an option for the POST /private/units request. - */ -struct TALER_MERCHANT_PostPrivateUnitsOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostPrivateUnitsOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N. - */ - const json_t *unit_name_long_i18n; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N. - */ - const json_t *unit_name_short_i18n; - - } details; - -}; - - -/** - * Handle for a POST /private/units request. - */ -struct TALER_MERCHANT_PostPrivateUnitsHandle; - - -/** - * Response details for a POST /private/units request. - */ -struct TALER_MERCHANT_PostPrivateUnitsResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_private_units_option_end_() \ - (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_END \ - } - -/** - * Set internationalized long names. - * - * @param j long names JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_units_option_unit_name_long_i18n(j) \ - (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N \ - , \ - .details.unit_name_long_i18n = (j) \ - } - -/** - * Set internationalized short names. - * - * @param j short names JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_private_units_option_unit_name_short_i18n(j) \ - (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ - { \ - .option = \ - TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N, \ - .details.unit_name_short_i18n = (j) \ - } - - -/** - * Set the requested options for the operation. - * - * @param ppuh 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_units_set_options_ ( - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateUnitsOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param ppuh 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_units_set_options(ppuh,...) \ - TALER_MERCHANT_post_private_units_set_options_ ( \ - ppuh, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostPrivateUnitsOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_private_units_option_end_ () } \ - )) - - -/** - * Set up POST /private/units operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @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 * -TALER_MERCHANT_post_private_units_create ( - struct GNUNET_CURL_Context *ctx, - 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); - - -#ifndef TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateUnitsCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/units request. - * - * @param cls closure - * @param pur response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateUnitsCallback)( - TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateUnitsResponse *pur); - - -/** - * Start POST /private/units operation. - * - * @param[in,out] ppuh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_units_start ( - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, - TALER_MERCHANT_PostPrivateUnitsCallback cb, - TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/units operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateUnitsCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppuh operation to cancel - */ -void -TALER_MERCHANT_post_private_units_cancel ( - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_UNITS_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-units.h b/src/include/taler/taler-merchant/post-private-units.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-units.h - * @brief C interface for POST /private/units of the merchant backend + * @brief C interface for the POST /private/units endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_UNITS_H @@ -26,64 +26,230 @@ /** + * Possible options for the POST /private/units request. + */ +enum TALER_MERCHANT_PostPrivateUnitsOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_END = 0, + + /** + * Internationalized long names (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N, + + /** + * Internationalized short names (JSON). + */ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N + +}; + + +/** + * Value for an option for the POST /private/units request. + */ +struct TALER_MERCHANT_PostPrivateUnitsOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostPrivateUnitsOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N. + */ + const json_t *unit_name_long_i18n; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N. + */ + const json_t *unit_name_short_i18n; + + } details; + +}; + + +/** * Handle for a POST /private/units request. */ -struct TALER_MERCHANT_UnitsPostHandle; +struct TALER_MERCHANT_PostPrivateUnitsHandle; /** - * Callback for a POST /private/units request. + * Response details for a POST /private/units request. + */ +struct TALER_MERCHANT_PostPrivateUnitsResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; + + +/** + * Terminate the list of the options. * - * @param cls closure - * @param hr HTTP response details + * @return the terminating object */ -typedef void -(*TALER_MERCHANT_UnitsPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +#define TALER_MERCHANT_post_private_units_option_end_() \ + (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_END \ + } + +/** + * Set internationalized long names. + * + * @param j long names JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_units_option_unit_name_long_i18n(j) \ + (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N \ + , \ + .details.unit_name_long_i18n = (j) \ + } + +/** + * Set internationalized short names. + * + * @param j short names JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_private_units_option_unit_name_short_i18n(j) \ + (const struct TALER_MERCHANT_PostPrivateUnitsOptionValue) \ + { \ + .option = \ + TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N, \ + .details.unit_name_short_i18n = (j) \ + } + + +/** + * Set the requested options for the operation. + * + * @param ppuh 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_units_set_options_ ( + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateUnitsOptionValue *options); /** - * Issue a POST /private/units request to create a new unit. + * Set the requested options for the operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ppuh 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_units_set_options(ppuh,...) \ + TALER_MERCHANT_post_private_units_set_options_ ( \ + ppuh, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostPrivateUnitsOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_private_units_option_end_ () } \ + )) + + +/** + * Set up POST /private/units operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend * @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 - * @param unit_name_long_i18n internationalized long names (JSON), or NULL - * @param unit_name_short_i18n internationalized short names (JSON), or NULL - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_UnitsPostHandle * -TALER_MERCHANT_units_post ( +struct TALER_MERCHANT_PostPrivateUnitsHandle * +TALER_MERCHANT_post_private_units_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + 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 json_t *unit_name_long_i18n, - const json_t *unit_name_short_i18n, - TALER_MERCHANT_UnitsPostCallback cb, - void *cb_cls); + bool unit_active); + + +#ifndef TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateUnitsCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/units request. + * + * @param cls closure + * @param pur response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateUnitsCallback)( + TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateUnitsResponse *pur); + + +/** + * Start POST /private/units operation. + * + * @param[in,out] ppuh operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_private_units_start ( + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, + TALER_MERCHANT_PostPrivateUnitsCallback cb, + TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/units request. + * Cancel POST /private/units operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateUnitsCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] uph handle to cancel + * @param[in] ppuh operation to cancel */ void -TALER_MERCHANT_units_post_cancel ( - struct TALER_MERCHANT_UnitsPostHandle *uph); +TALER_MERCHANT_post_private_units_cancel ( + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_UNITS_H */ diff --git a/src/include/taler/taler-merchant/post-private-webhooks-new.h b/src/include/taler/taler-merchant/post-private-webhooks-new.h @@ -1,123 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-private-webhooks-new.h - * @brief C interface for the POST /private/webhooks endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_PRIVATE_WEBHOOKS_NEW_H -#define _TALER_MERCHANT__POST_PRIVATE_WEBHOOKS_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Handle for a POST /private/webhooks request. - */ -struct TALER_MERCHANT_PostPrivateWebhooksHandle; - - -/** - * Response details for a POST /private/webhooks request. - */ -struct TALER_MERCHANT_PostPrivateWebhooksResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - -}; - - -/** - * Set up POST /private/webhooks operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param webhook_id identifier for the new webhook - * @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 * -TALER_MERCHANT_post_private_webhooks_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - 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 - - -#ifndef TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostPrivateWebhooksCallback. - */ -#define TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE */ - -/** - * Callback for a POST /private/webhooks request. - * - * @param cls closure - * @param wpr response details - */ -typedef void -(*TALER_MERCHANT_PostPrivateWebhooksCallback)( - TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostPrivateWebhooksResponse *wpr); - - -/** - * Start POST /private/webhooks operation. - * - * @param[in,out] ppwh operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_private_webhooks_start ( - struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, - TALER_MERCHANT_PostPrivateWebhooksCallback cb, - TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /private/webhooks operation. This function must not be - * called by clients after the TALER_MERCHANT_PostPrivateWebhooksCallback - * has been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] ppwh operation to cancel - */ -void -TALER_MERCHANT_post_private_webhooks_cancel ( - struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh); - - -#endif /* _TALER_MERCHANT__POST_PRIVATE_WEBHOOKS_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-private-webhooks.h b/src/include/taler/taler-merchant/post-private-webhooks.h @@ -16,7 +16,7 @@ */ /** * @file include/taler/taler-merchant/post-private-webhooks.h - * @brief C interface for POST /private/webhooks of the merchant backend + * @brief C interface for the POST /private/webhooks endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_PRIVATE_WEBHOOKS_H @@ -28,58 +28,96 @@ /** * Handle for a POST /private/webhooks request. */ -struct TALER_MERCHANT_WebhooksPostHandle; +struct TALER_MERCHANT_PostPrivateWebhooksHandle; /** - * Callback for a POST /private/webhooks request. - * - * @param cls closure - * @param hr HTTP response details + * Response details for a POST /private/webhooks request. */ -typedef void -(*TALER_MERCHANT_WebhooksPostCallback)( - void *cls, - const struct TALER_MERCHANT_HttpResponse *hr); +struct TALER_MERCHANT_PostPrivateWebhooksResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + +}; /** - * Issue a POST /private/webhooks request to create a new webhook. + * Set up POST /private/webhooks operation. + * Note that you must explicitly start the operation after + * possibly setting options. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param ctx the context + * @param url base URL of the merchant backend * @param webhook_id identifier for the new webhook * @param event_type event type that triggers this webhook - * @param url URL to send notifications to + * @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 - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_WebhooksPostHandle * -TALER_MERCHANT_webhooks_post ( +struct TALER_MERCHANT_PostPrivateWebhooksHandle * +TALER_MERCHANT_post_private_webhooks_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *webhook_id, const char *event_type, - const char *url, + const char *notification_url, const char *http_method, - const char *header_template, - const char *body_template, - TALER_MERCHANT_WebhooksPostCallback cb, - void *cb_cls); + const char *header_template, // FIXME: use set_option + const char *body_template); // FIXME: use set_option + + +#ifndef TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE +/** + * Type of the closure used by + * the #TALER_MERCHANT_PostPrivateWebhooksCallback. + */ +#define TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE */ + +/** + * Callback for a POST /private/webhooks request. + * + * @param cls closure + * @param wpr response details + */ +typedef void +(*TALER_MERCHANT_PostPrivateWebhooksCallback)( + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostPrivateWebhooksResponse *wpr); + + +/** + * Start POST /private/webhooks operation. + * + * @param[in,out] ppwh operation to start + * @param cb function to call with the merchant's result + * @param cb_cls closure for @a cb + * @return status code, #TALER_EC_NONE on success + */ +enum TALER_ErrorCode +TALER_MERCHANT_post_private_webhooks_start ( + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, + TALER_MERCHANT_PostPrivateWebhooksCallback cb, + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /private/webhooks request. + * Cancel POST /private/webhooks operation. This function must not be + * called by clients after the TALER_MERCHANT_PostPrivateWebhooksCallback + * has been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] wph handle to cancel + * @param[in] ppwh operation to cancel */ void -TALER_MERCHANT_webhooks_post_cancel ( - struct TALER_MERCHANT_WebhooksPostHandle *wph); +TALER_MERCHANT_post_private_webhooks_cancel ( + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh); -#endif +#endif /* _TALER_MERCHANT__POST_PRIVATE_WEBHOOKS_H */ diff --git a/src/include/taler/taler-merchant/post-templates-TEMPLATE_ID-new.h b/src/include/taler/taler-merchant/post-templates-TEMPLATE_ID-new.h @@ -1,298 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file include/taler/taler-merchant/post-templates-TEMPLATE_ID-new.h - * @brief C interface for the POST /templates/$TEMPLATE_ID endpoint - * @author Christian Grothoff - */ -#ifndef _TALER_MERCHANT__POST_TEMPLATES_TEMPLATE_ID_NEW_H -#define _TALER_MERCHANT__POST_TEMPLATES_TEMPLATE_ID_NEW_H - -#include <taler/taler-merchant/common.h> - - -/** - * Possible options for the POST /templates/$TEMPLATE_ID request. - */ -enum TALER_MERCHANT_PostTemplatesOption -{ - /** - * End of list of options. - */ - TALER_MERCHANT_POST_TEMPLATES_OPTION_END = 0, - - /** - * Order summary. - */ - TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY, - - /** - * Total amount for the order. - */ - TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT, - - /** - * Detailed contract customization (JSON). - */ - TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS - -}; - - -/** - * Value for an option for the POST /templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_PostTemplatesOptionValue -{ - - /** - * Type of the option being set. - */ - enum TALER_MERCHANT_PostTemplatesOption option; - - /** - * Specific option value. - */ - union - { - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY. - */ - const char *summary; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT. - */ - const struct TALER_Amount *amount; - - /** - * Value if @e option is - * #TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS. - */ - const json_t *details; - - } details; - -}; - - -/** - * Handle for a POST /templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_PostTemplatesHandle; - - -/** - * Response details for a POST /templates/$TEMPLATE_ID request. - */ -struct TALER_MERCHANT_PostTemplatesResponse -{ - - /** - * HTTP response details. - */ - struct TALER_MERCHANT_HttpResponse hr; - - /** - * Details depending on the HTTP status code. - */ - union - { - - /** - * Details on #MHD_HTTP_OK. - */ - struct - { - - /** - * Identifier of the created order. - */ - const char *order_id; - - /** - * Claim token, or NULL. - */ - const struct TALER_ClaimTokenP *token; - - /** - * Payment deadline. - */ - struct GNUNET_TIME_Timestamp pay_deadline; - - } ok; - - } details; - -}; - - -/** - * Terminate the list of the options. - * - * @return the terminating object - */ -#define TALER_MERCHANT_post_templates_option_end_() \ - (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_END \ - } - -/** - * Set order summary. - * - * @param s summary string - * @return representation of the option - */ -#define TALER_MERCHANT_post_templates_option_summary(s) \ - (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY, \ - .details.summary = (s) \ - } - -/** - * Set total amount. - * - * @param a amount - * @return representation of the option - */ -#define TALER_MERCHANT_post_templates_option_amount(a) \ - (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT, \ - .details.amount = (a) \ - } - -/** - * Set detailed contract customization. - * - * @param d details JSON object - * @return representation of the option - */ -#define TALER_MERCHANT_post_templates_option_details(d) \ - (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ - { \ - .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS, \ - .details.details = (d) \ - } - - -/** - * Set the requested options for the operation. - * - * @param pth 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_templates_set_options_ ( - struct TALER_MERCHANT_PostTemplatesHandle *pth, - unsigned int num_options, - const struct TALER_MERCHANT_PostTemplatesOptionValue *options); - - -/** - * Set the requested options for the operation. - * - * @param pth 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_templates_set_options(pth,...) \ - TALER_MERCHANT_post_templates_set_options_ ( \ - pth, \ - TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ - ((const struct TALER_MERCHANT_PostTemplatesOptionValue[]) \ - {__VA_ARGS__, TALER_MERCHANT_post_templates_option_end_ () } \ - )) - - -/** - * Set up POST /templates/$TEMPLATE_ID operation. - * Note that you must explicitly start the operation after - * possibly setting options. - * - * @param ctx the context - * @param url base URL of the merchant backend - * @param template_id identifier of the template to use - * @return handle to operation - */ -struct TALER_MERCHANT_PostTemplatesHandle * -TALER_MERCHANT_post_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id); - - -#ifndef TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE -/** - * Type of the closure used by - * the #TALER_MERCHANT_PostTemplatesCallback. - */ -#define TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE void -#endif /* TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE */ - -/** - * Callback for a POST /templates/$TEMPLATE_ID request. - * - * @param cls closure - * @param ptr response details - */ -typedef void -(*TALER_MERCHANT_PostTemplatesCallback)( - TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cls, - const struct TALER_MERCHANT_PostTemplatesResponse *ptr); - - -/** - * Start POST /templates/$TEMPLATE_ID operation. - * - * @param[in,out] pth operation to start - * @param cb function to call with the merchant's result - * @param cb_cls closure for @a cb - * @return status code, #TALER_EC_NONE on success - */ -enum TALER_ErrorCode -TALER_MERCHANT_post_templates_start ( - struct TALER_MERCHANT_PostTemplatesHandle *pth, - TALER_MERCHANT_PostTemplatesCallback cb, - TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cb_cls); - - -/** - * Cancel POST /templates/$TEMPLATE_ID operation. This function must not be - * called by clients after the TALER_MERCHANT_PostTemplatesCallback has - * been invoked (as in those cases it'll be called internally by the - * implementation already). - * - * @param[in] pth operation to cancel - */ -void -TALER_MERCHANT_post_templates_cancel ( - struct TALER_MERCHANT_PostTemplatesHandle *pth); - - -#endif /* _TALER_MERCHANT__POST_TEMPLATES_TEMPLATE_ID_NEW_H */ diff --git a/src/include/taler/taler-merchant/post-templates-TEMPLATE_ID.h b/src/include/taler/taler-merchant/post-templates-TEMPLATE_ID.h @@ -16,77 +16,283 @@ */ /** * @file include/taler/taler-merchant/post-templates-TEMPLATE_ID.h - * @brief C interface for POST /templates/$TEMPLATE_ID (create order from template) - * of the merchant backend + * @brief C interface for the POST /templates/$TEMPLATE_ID endpoint * @author Christian Grothoff */ #ifndef _TALER_MERCHANT__POST_TEMPLATES_TEMPLATE_ID_H #define _TALER_MERCHANT__POST_TEMPLATES_TEMPLATE_ID_H #include <taler/taler-merchant/common.h> -#include <taler/taler-merchant/post-private-orders.h> + + +/** + * Possible options for the POST /templates/$TEMPLATE_ID request. + */ +enum TALER_MERCHANT_PostTemplatesOption +{ + /** + * End of list of options. + */ + TALER_MERCHANT_POST_TEMPLATES_OPTION_END = 0, + + /** + * Order summary. + */ + TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY, + + /** + * Total amount for the order. + */ + TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT, + + /** + * Detailed contract customization (JSON). + */ + TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS + +}; + + +/** + * Value for an option for the POST /templates/$TEMPLATE_ID request. + */ +struct TALER_MERCHANT_PostTemplatesOptionValue +{ + + /** + * Type of the option being set. + */ + enum TALER_MERCHANT_PostTemplatesOption option; + + /** + * Specific option value. + */ + union + { + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY. + */ + const char *summary; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT. + */ + const struct TALER_Amount *amount; + + /** + * Value if @e option is + * #TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS. + */ + const json_t *details; + + } details; + +}; /** * Handle for a POST /templates/$TEMPLATE_ID request. */ -struct TALER_MERCHANT_UsingTemplatesPostHandle; +struct TALER_MERCHANT_PostTemplatesHandle; + + +/** + * Response details for a POST /templates/$TEMPLATE_ID request. + */ +struct TALER_MERCHANT_PostTemplatesResponse +{ + + /** + * HTTP response details. + */ + struct TALER_MERCHANT_HttpResponse hr; + + /** + * Details depending on the HTTP status code. + */ + union + { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + + /** + * Identifier of the created order. + */ + const char *order_id; + + /** + * Claim token, or NULL. + */ + const struct TALER_ClaimTokenP *token; + + /** + * Payment deadline. + */ + struct GNUNET_TIME_Timestamp pay_deadline; + + } ok; + + } details; + +}; + + +/** + * Terminate the list of the options. + * + * @return the terminating object + */ +#define TALER_MERCHANT_post_templates_option_end_() \ + (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_END \ + } + +/** + * Set order summary. + * + * @param s summary string + * @return representation of the option + */ +#define TALER_MERCHANT_post_templates_option_summary(s) \ + (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY, \ + .details.summary = (s) \ + } + +/** + * Set total amount. + * + * @param a amount + * @return representation of the option + */ +#define TALER_MERCHANT_post_templates_option_amount(a) \ + (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT, \ + .details.amount = (a) \ + } + +/** + * Set detailed contract customization. + * + * @param d details JSON object + * @return representation of the option + */ +#define TALER_MERCHANT_post_templates_option_details(d) \ + (const struct TALER_MERCHANT_PostTemplatesOptionValue) \ + { \ + .option = TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS, \ + .details.details = (d) \ + } /** - * Issue a POST /templates/$TEMPLATE_ID request to create an order from - * a template using a simple amount and summary. + * Set the requested options for the operation. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend + * @param pth 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_templates_set_options_ ( + struct TALER_MERCHANT_PostTemplatesHandle *pth, + unsigned int num_options, + const struct TALER_MERCHANT_PostTemplatesOptionValue *options); + + +/** + * Set the requested options for the operation. + * + * @param pth 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_templates_set_options(pth,...) \ + TALER_MERCHANT_post_templates_set_options_ ( \ + pth, \ + TALER_MERCHANT_COMMON_OPTIONS_ARRAY_MAX_SIZE, \ + ((const struct TALER_MERCHANT_PostTemplatesOptionValue[]) \ + {__VA_ARGS__, TALER_MERCHANT_post_templates_option_end_ () } \ + )) + + +/** + * Set up POST /templates/$TEMPLATE_ID operation. + * Note that you must explicitly start the operation after + * possibly setting options. + * + * @param ctx the context + * @param url base URL of the merchant backend * @param template_id identifier of the template to use - * @param summary order summary - * @param amount total amount for the order - * @param cb callback to invoke with the result - * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return handle to operation */ -struct TALER_MERCHANT_UsingTemplatesPostHandle * -TALER_MERCHANT_using_templates_post ( +struct TALER_MERCHANT_PostTemplatesHandle * +TALER_MERCHANT_post_templates_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - const char *summary, - const struct TALER_Amount *amount, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls); + const char *url, + const char *template_id); +#ifndef TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE /** - * Issue a POST /templates/$TEMPLATE_ID request to create an order from - * a template using detailed contract customization. + * Type of the closure used by + * the #TALER_MERCHANT_PostTemplatesCallback. + */ +#define TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE void +#endif /* TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE */ + +/** + * Callback for a POST /templates/$TEMPLATE_ID request. * - * @param ctx CURL context to use - * @param backend_url base URL of the merchant backend - * @param template_id identifier of the template to use - * @param details JSON object with template-specific order details - * @param cb callback to invoke with the result + * @param cls closure + * @param ptr response details + */ +typedef void +(*TALER_MERCHANT_PostTemplatesCallback)( + TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cls, + const struct TALER_MERCHANT_PostTemplatesResponse *ptr); + + +/** + * Start POST /templates/$TEMPLATE_ID operation. + * + * @param[in,out] pth operation to start + * @param cb function to call with the merchant's result * @param cb_cls closure for @a cb - * @return handle for the request, NULL on hard error + * @return status code, #TALER_EC_NONE on success */ -struct TALER_MERCHANT_UsingTemplatesPostHandle * -TALER_MERCHANT_using_templates_post2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - const json_t *details, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls); +enum TALER_ErrorCode +TALER_MERCHANT_post_templates_start ( + struct TALER_MERCHANT_PostTemplatesHandle *pth, + TALER_MERCHANT_PostTemplatesCallback cb, + TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cb_cls); /** - * Cancel a POST /templates/$TEMPLATE_ID request. + * Cancel POST /templates/$TEMPLATE_ID operation. This function must not be + * called by clients after the TALER_MERCHANT_PostTemplatesCallback has + * been invoked (as in those cases it'll be called internally by the + * implementation already). * - * @param[in] utph handle to cancel + * @param[in] pth operation to cancel */ void -TALER_MERCHANT_using_templates_post_cancel ( - struct TALER_MERCHANT_UsingTemplatesPostHandle *utph); +TALER_MERCHANT_post_templates_cancel ( + struct TALER_MERCHANT_PostTemplatesHandle *pth); -#endif +#endif /* _TALER_MERCHANT__POST_TEMPLATES_TEMPLATE_ID_H */ diff --git a/src/include/taler/taler_merchant_service.h b/src/include/taler/taler_merchant_service.h @@ -33,70 +33,70 @@ #define TALER_MERCHANT_API_VERSION 0x000C0000 #include <taler/taler-merchant/common.h> -#include <taler/taler-merchant/get-config-new.h> -#include <taler/taler-merchant/get-management-instances-new.h> -#include <taler/taler-merchant/get-management-instances-INSTANCE-new.h> -#include <taler/taler-merchant/get-private-kyc-new.h> -#include <taler/taler-merchant/get-private-statistics-amount-SLUG-new.h> -#include <taler/taler-merchant/get-private-statistics-counter-SLUG-new.h> -#include <taler/taler-merchant/delete-management-instances-INSTANCE-new.h> -#include <taler/taler-merchant/patch-management-instances-INSTANCE-new.h> -#include <taler/taler-merchant/post-management-instances-new.h> -#include <taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h> -#include <taler/taler-merchant/post-private-token-new.h> -#include <taler/taler-merchant/delete-private-tokens-SERIAL-new.h> -#include <taler/taler-merchant/get-private-orders-new.h> -#include <taler/taler-merchant/post-private-orders-new.h> -#include <taler/taler-merchant/get-private-orders-ORDER_ID-new.h> -#include <taler/taler-merchant/get-orders-ORDER_ID-new.h> -#include <taler/taler-merchant/delete-private-orders-ORDER_ID-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-abort-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-claim-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-paid-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-pay-new.h> -#include <taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-refund-new.h> -#include <taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h> -#include <taler/taler-merchant/get-private-products-new.h> -#include <taler/taler-merchant/get-private-products-PRODUCT_ID-new.h> -#include <taler/taler-merchant/post-private-products-new.h> -#include <taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h> -#include <taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h> -#include <taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h> -#include <taler/taler-merchant/get-products-IMAGE_HASH-image-new.h> -#include <taler/taler-merchant/get-private-transfers-new.h> -#include <taler/taler-merchant/post-private-transfers-new.h> -#include <taler/taler-merchant/delete-private-transfers-TID-new.h> -#include <taler/taler-merchant/get-private-accounts-new.h> -#include <taler/taler-merchant/get-private-accounts-H_WIRE-new.h> -#include <taler/taler-merchant/post-private-accounts-new.h> -#include <taler/taler-merchant/patch-private-accounts-H_WIRE-new.h> -#include <taler/taler-merchant/delete-private-accounts-H_WIRE-new.h> -#include <taler/taler-merchant/get-private-otp-devices-new.h> -#include <taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h> -#include <taler/taler-merchant/post-private-otp-devices-new.h> -#include <taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h> -#include <taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h> -#include <taler/taler-merchant/get-private-templates-new.h> -#include <taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h> -#include <taler/taler-merchant/post-private-templates-new.h> -#include <taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h> -#include <taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h> -#include <taler/taler-merchant/post-templates-TEMPLATE_ID-new.h> -#include <taler/taler-merchant/get-templates-TEMPLATE_ID-new.h> +#include <taler/taler-merchant/get-config.h> +#include <taler/taler-merchant/get-management-instances.h> +#include <taler/taler-merchant/get-management-instances-INSTANCE.h> +#include <taler/taler-merchant/get-private-kyc.h> +#include <taler/taler-merchant/get-private-statistics-amount-SLUG.h> +#include <taler/taler-merchant/get-private-statistics-counter-SLUG.h> +#include <taler/taler-merchant/delete-management-instances-INSTANCE.h> +#include <taler/taler-merchant/patch-management-instances-INSTANCE.h> +#include <taler/taler-merchant/post-management-instances.h> +#include <taler/taler-merchant/post-management-instances-INSTANCE-auth.h> +#include <taler/taler-merchant/post-private-token.h> +#include <taler/taler-merchant/delete-private-tokens-SERIAL.h> +#include <taler/taler-merchant/get-private-orders.h> +#include <taler/taler-merchant/post-private-orders.h> +#include <taler/taler-merchant/get-private-orders-ORDER_ID.h> +#include <taler/taler-merchant/get-orders-ORDER_ID.h> +#include <taler/taler-merchant/delete-private-orders-ORDER_ID.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-abort.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-claim.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-paid.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-pay.h> +#include <taler/taler-merchant/post-private-orders-ORDER_ID-refund.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-refund.h> +#include <taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h> +#include <taler/taler-merchant/get-private-products.h> +#include <taler/taler-merchant/get-private-products-PRODUCT_ID.h> +#include <taler/taler-merchant/post-private-products.h> +#include <taler/taler-merchant/patch-private-products-PRODUCT_ID.h> +#include <taler/taler-merchant/delete-private-products-PRODUCT_ID.h> +#include <taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h> +#include <taler/taler-merchant/get-products-IMAGE_HASH-image.h> +#include <taler/taler-merchant/get-private-transfers.h> +#include <taler/taler-merchant/post-private-transfers.h> +#include <taler/taler-merchant/delete-private-transfers-TID.h> +#include <taler/taler-merchant/get-private-accounts.h> +#include <taler/taler-merchant/get-private-accounts-H_WIRE.h> +#include <taler/taler-merchant/post-private-accounts.h> +#include <taler/taler-merchant/patch-private-accounts-H_WIRE.h> +#include <taler/taler-merchant/delete-private-accounts-H_WIRE.h> +#include <taler/taler-merchant/get-private-otp-devices.h> +#include <taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h> +#include <taler/taler-merchant/post-private-otp-devices.h> +#include <taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h> +#include <taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h> +#include <taler/taler-merchant/get-private-templates.h> +#include <taler/taler-merchant/get-private-templates-TEMPLATE_ID.h> +#include <taler/taler-merchant/post-private-templates.h> +#include <taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h> +#include <taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h> +#include <taler/taler-merchant/post-templates-TEMPLATE_ID.h> +#include <taler/taler-merchant/get-templates-TEMPLATE_ID.h> #include \ - <taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.h> -#include <taler/taler-merchant/post-private-tokenfamilies-new.h> -#include <taler/taler-merchant/get-private-webhooks-new.h> -#include <taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h> -#include <taler/taler-merchant/post-private-webhooks-new.h> -#include <taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h> -#include <taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h> -#include <taler/taler-merchant/get-private-units-new.h> -#include <taler/taler-merchant/get-private-units-UNIT-new.h> -#include <taler/taler-merchant/post-private-units-new.h> -#include <taler/taler-merchant/patch-private-units-UNIT-new.h> -#include <taler/taler-merchant/delete-private-units-UNIT-new.h> -#include <taler/taler-merchant/post-private-categories-new.h> + <taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG.h> +#include <taler/taler-merchant/post-private-tokenfamilies.h> +#include <taler/taler-merchant/get-private-webhooks.h> +#include <taler/taler-merchant/get-private-webhooks-WEBHOOK_ID.h> +#include <taler/taler-merchant/post-private-webhooks.h> +#include <taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h> +#include <taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h> +#include <taler/taler-merchant/get-private-units.h> +#include <taler/taler-merchant/get-private-units-UNIT.h> +#include <taler/taler-merchant/post-private-units.h> +#include <taler/taler-merchant/patch-private-units-UNIT.h> +#include <taler/taler-merchant/delete-private-units-UNIT.h> +#include <taler/taler-merchant/post-private-categories.h> #endif diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am @@ -16,70 +16,70 @@ libtalermerchant_la_LDFLAGS = \ libtalermerchant_la_SOURCES = \ merchant_api_curl_defaults.c merchant_api_curl_defaults.h \ merchant_api_common.c merchant_api_common.h \ - merchant_api_delete-management-instances-INSTANCE-new.c \ - merchant_api_delete-private-accounts-H_WIRE-new.c \ - merchant_api_delete-private-orders-ORDER_ID-new.c \ - merchant_api_delete-private-otp-devices-DEVICE_ID-new.c \ - merchant_api_delete-private-products-PRODUCT_ID-new.c \ - merchant_api_delete-private-templates-TEMPLATE_ID-new.c \ - merchant_api_delete-private-tokens-SERIAL-new.c \ - merchant_api_delete-private-transfers-TID-new.c \ - merchant_api_delete-private-units-UNIT-new.c \ - merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c \ - merchant_api_get-config-new.c \ - merchant_api_get-management-instances-new.c \ - merchant_api_get-management-instances-INSTANCE-new.c \ - merchant_api_get-orders-ORDER_ID-new.c \ - merchant_api_get-private-accounts-new.c \ - merchant_api_get-private-accounts-H_WIRE-new.c \ - merchant_api_get-private-kyc-new.c \ - merchant_api_get-private-orders-new.c \ - merchant_api_get-private-orders-ORDER_ID-new.c \ - merchant_api_get-private-otp-devices-new.c \ - merchant_api_get-private-otp-devices-DEVICE_ID-new.c \ - merchant_api_get-private-products-new.c \ - merchant_api_get-private-products-PRODUCT_ID-new.c \ - merchant_api_get-private-statistics-amount-SLUG-new.c \ - merchant_api_get-private-statistics-counter-SLUG-new.c \ - merchant_api_get-private-templates-new.c \ - merchant_api_get-private-templates-TEMPLATE_ID-new.c \ - merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c \ - merchant_api_get-private-transfers-new.c \ - merchant_api_get-private-units-new.c \ - merchant_api_get-private-units-UNIT-new.c \ - merchant_api_get-private-webhooks-new.c \ - merchant_api_get-private-webhooks-WEBHOOK_ID-new.c \ - merchant_api_get-products-IMAGE_HASH-image-new.c \ - merchant_api_get-templates-TEMPLATE_ID-new.c \ - merchant_api_patch-management-instances-INSTANCE-new.c \ - merchant_api_patch-private-accounts-H_WIRE-new.c \ - merchant_api_patch-private-orders-ORDER_ID-forget-new.c \ - merchant_api_patch-private-otp-devices-DEVICE_ID-new.c \ - merchant_api_patch-private-products-PRODUCT_ID-new.c \ - merchant_api_patch-private-templates-TEMPLATE_ID-new.c \ - merchant_api_patch-private-units-UNIT-new.c \ - merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c \ - merchant_api_post-management-instances-new.c \ - merchant_api_post-management-instances-INSTANCE-auth-new.c \ - merchant_api_post-orders-ORDER_ID-abort-new.c \ - merchant_api_post-orders-ORDER_ID-claim-new.c \ - merchant_api_post-orders-ORDER_ID-paid-new.c \ - merchant_api_post-orders-ORDER_ID-pay-new.c \ - merchant_api_post-orders-ORDER_ID-refund-new.c \ - merchant_api_post-private-accounts-new.c \ - merchant_api_post-private-categories-new.c \ - merchant_api_post-private-orders-new.c \ - merchant_api_post-private-orders-ORDER_ID-refund-new.c \ - merchant_api_post-private-otp-devices-new.c \ - merchant_api_post-private-products-new.c \ - merchant_api_post-private-products-PRODUCT_ID-lock-new.c \ - merchant_api_post-private-templates-new.c \ - merchant_api_post-private-token-new.c \ - merchant_api_post-private-tokenfamilies-new.c \ - merchant_api_post-private-transfers-new.c \ - merchant_api_post-private-units-new.c \ - merchant_api_post-private-webhooks-new.c \ - merchant_api_post-templates-TEMPLATE_ID-new.c + merchant_api_delete-management-instances-INSTANCE.c \ + merchant_api_delete-private-accounts-H_WIRE.c \ + merchant_api_delete-private-orders-ORDER_ID.c \ + merchant_api_delete-private-otp-devices-DEVICE_ID.c \ + merchant_api_delete-private-products-PRODUCT_ID.c \ + merchant_api_delete-private-templates-TEMPLATE_ID.c \ + merchant_api_delete-private-tokens-SERIAL.c \ + merchant_api_delete-private-transfers-TID.c \ + merchant_api_delete-private-units-UNIT.c \ + merchant_api_delete-private-webhooks-WEBHOOK_ID.c \ + merchant_api_get-config.c \ + merchant_api_get-management-instances.c \ + merchant_api_get-management-instances-INSTANCE.c \ + merchant_api_get-orders-ORDER_ID.c \ + merchant_api_get-private-accounts.c \ + merchant_api_get-private-accounts-H_WIRE.c \ + merchant_api_get-private-kyc.c \ + merchant_api_get-private-orders.c \ + merchant_api_get-private-orders-ORDER_ID.c \ + merchant_api_get-private-otp-devices.c \ + merchant_api_get-private-otp-devices-DEVICE_ID.c \ + merchant_api_get-private-products.c \ + merchant_api_get-private-products-PRODUCT_ID.c \ + merchant_api_get-private-statistics-amount-SLUG.c \ + merchant_api_get-private-statistics-counter-SLUG.c \ + merchant_api_get-private-templates.c \ + merchant_api_get-private-templates-TEMPLATE_ID.c \ + merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c \ + merchant_api_get-private-transfers.c \ + merchant_api_get-private-units.c \ + merchant_api_get-private-units-UNIT.c \ + merchant_api_get-private-webhooks.c \ + merchant_api_get-private-webhooks-WEBHOOK_ID.c \ + merchant_api_get-products-IMAGE_HASH-image.c \ + merchant_api_get-templates-TEMPLATE_ID.c \ + merchant_api_patch-management-instances-INSTANCE.c \ + merchant_api_patch-private-accounts-H_WIRE.c \ + merchant_api_patch-private-orders-ORDER_ID-forget.c \ + merchant_api_patch-private-otp-devices-DEVICE_ID.c \ + merchant_api_patch-private-products-PRODUCT_ID.c \ + merchant_api_patch-private-templates-TEMPLATE_ID.c \ + merchant_api_patch-private-units-UNIT.c \ + merchant_api_patch-private-webhooks-WEBHOOK_ID.c \ + merchant_api_post-management-instances.c \ + merchant_api_post-management-instances-INSTANCE-auth.c \ + merchant_api_post-orders-ORDER_ID-abort.c \ + merchant_api_post-orders-ORDER_ID-claim.c \ + merchant_api_post-orders-ORDER_ID-paid.c \ + merchant_api_post-orders-ORDER_ID-pay.c \ + merchant_api_post-orders-ORDER_ID-refund.c \ + merchant_api_post-private-accounts.c \ + merchant_api_post-private-categories.c \ + merchant_api_post-private-orders.c \ + merchant_api_post-private-orders-ORDER_ID-refund.c \ + merchant_api_post-private-otp-devices.c \ + merchant_api_post-private-products.c \ + merchant_api_post-private-products-PRODUCT_ID-lock.c \ + merchant_api_post-private-templates.c \ + merchant_api_post-private-token.c \ + merchant_api_post-private-tokenfamilies.c \ + merchant_api_post-private-transfers.c \ + merchant_api_post-private-units.c \ + merchant_api_post-private-webhooks.c \ + merchant_api_post-templates-TEMPLATE_ID.c libtalermerchant_la_LIBADD = \ -ltalerexchange \ @@ -96,9 +96,9 @@ libtalermerchant_la_LIBADD = \ if HAVE_DONAU libtalermerchant_la_SOURCES += \ - merchant_api_get-private-donau-new.c \ - merchant_api_post-private-donau-new.c \ - merchant_api_delete-private-donau-DONAU_SERIAL-new.c + merchant_api_get-private-donau.c \ + merchant_api_post-private-donau.c \ + merchant_api_delete-private-donau-DONAU_SERIAL.c libtalermerchant_la_LIBADD += \ -ldonaujson \ diff --git a/src/lib/merchant_api_delete-management-instances-INSTANCE-new.c b/src/lib/merchant_api_delete-management-instances-INSTANCE-new.c @@ -1,240 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-management-instances-INSTANCE-new.c - * @brief Implementation of the DELETE /management/instances/$INSTANCE request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-management-instances-INSTANCE-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /management/instances/$INSTANCE operation. - */ -struct TALER_MERCHANT_DeleteManagementInstanceHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeleteManagementInstanceCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the instance to delete. - */ - char *instance_id; - - /** - * Whether to purge (hard delete) the instance. - */ - bool purge; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /management/instances/$INSTANCE request. - * - * @param cls the `struct TALER_MERCHANT_DeleteManagementInstanceHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_instance_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeleteManagementInstanceResponse dir = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dih->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /management/instances/$INSTANCE DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dir.hr.ec = TALER_JSON_get_error_code (json); - dir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dir.hr.ec = TALER_JSON_get_error_code (json); - dir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dir.hr.ec = TALER_JSON_get_error_code (json); - dir.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dir.hr.ec = TALER_JSON_get_error_code (json); - dir.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /management/instances/$INSTANCE\n", - (unsigned int) response_code, - (int) dir.hr.ec); - break; - } - dih->cb (dih->cb_cls, - &dir); - TALER_MERCHANT_delete_management_instance_cancel (dih); -} - - -struct TALER_MERCHANT_DeleteManagementInstanceHandle * -TALER_MERCHANT_delete_management_instance_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id) -{ - struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih; - - dih = GNUNET_new (struct TALER_MERCHANT_DeleteManagementInstanceHandle); - dih->ctx = ctx; - dih->base_url = GNUNET_strdup (url); - if (NULL != instance_id) - dih->instance_id = GNUNET_strdup (instance_id); - return dih; -} - - -void -TALER_MERCHANT_delete_management_instance_set_options_ ( - struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle, - unsigned int num_options, - const struct TALER_MERCHANT_DeleteManagementInstanceOptionValue options[]) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END: - return; - case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_PURGE: - handle->purge = true; - break; - } - } -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_management_instance_start ( - struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih, - TALER_MERCHANT_DeleteManagementInstanceCallback cb, - TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dih->cb = cb; - dih->cb_cls = cb_cls; - if (NULL != dih->instance_id) - { - char *path; - - GNUNET_asprintf (&path, - "management/instances/%s", - dih->instance_id); - dih->url = TALER_url_join (dih->base_url, - path, - "purge", - (dih->purge) ? "yes" : NULL, - NULL); - GNUNET_free (path); - } - else - { - /* backend_url is already identifying the instance */ - dih->url = TALER_url_join (dih->base_url, - "private", - "purge", - (dih->purge) ? "yes" : NULL, - NULL); - } - if (NULL == dih->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dih->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dih->job = GNUNET_CURL_job_add (dih->ctx, - eh, - &handle_delete_instance_finished, - dih); - if (NULL == dih->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_management_instance_cancel ( - struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih) -{ - if (NULL != dih->job) - { - GNUNET_CURL_job_cancel (dih->job); - dih->job = NULL; - } - GNUNET_free (dih->url); - GNUNET_free (dih->instance_id); - GNUNET_free (dih->base_url); - GNUNET_free (dih); -} - - -/* end of merchant_api_delete-management-instances-INSTANCE-new.c */ diff --git a/src/lib/merchant_api_delete-management-instances-INSTANCE.c b/src/lib/merchant_api_delete-management-instances-INSTANCE.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018, 2020 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-management-instances-INSTANCE.c - * @brief Implementation of the DELETE /instance/$ID request of the merchant's HTTP API + * @file merchant_api_delete-management-instances-INSTANCE-new.c + * @brief Implementation of the DELETE /management/instances/$INSTANCE request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-management-instances-INSTANCE.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /instances/$ID operation. + * Handle for a DELETE /management/instances/$INSTANCE operation. */ -struct TALER_MERCHANT_InstanceDeleteHandle +struct TALER_MERCHANT_DeleteManagementInstanceHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,35 @@ struct TALER_MERCHANT_InstanceDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstanceDeleteCallback cb; + TALER_MERCHANT_DeleteManagementInstanceCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Identifier of the instance to delete. + */ + char *instance_id; + + /** + * Whether to purge (hard delete) the instance. + */ + bool purge; }; /** * Function called when we're done processing the - * HTTP GET /instances/$ID request. + * HTTP DELETE /management/instances/$INSTANCE request. * - * @param cls the `struct TALER_MERCHANT_InstanceDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeleteManagementInstanceHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,160 +90,151 @@ handle_delete_instance_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_InstanceDeleteHandle *idh = cls; + struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeleteManagementInstanceResponse dir = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - idh->job = NULL; + dih->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /instances/$ID response with status code %u\n", + "Got /management/instances/$INSTANCE DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dir.hr.ec = TALER_JSON_get_error_code (json); + dir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: + dir.hr.ec = TALER_JSON_get_error_code (json); + dir.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_CONFLICT: + dir.hr.ec = TALER_JSON_get_error_code (json); + dir.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dir.hr.ec = TALER_JSON_get_error_code (json); + dir.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /instance/ID\n", + "Unexpected response code %u/%d for DELETE /management/instances/$INSTANCE\n", (unsigned int) response_code, - (int) hr.ec); + (int) dir.hr.ec); break; } - idh->cb (idh->cb_cls, - &hr); - TALER_MERCHANT_instance_delete_cancel (idh); + dih->cb (dih->cb_cls, + &dir); + TALER_MERCHANT_delete_management_instance_cancel (dih); } -/** - * Delete the private key of an instance of a backend, thereby disabling the - * instance for future requests. Will preserve the other instance data - * (i.e. for taxation). - * - * @param ctx the context - * @param backend_url HTTP base URL for the backend - * @param instance_id which instance should be deleted - * @param purge purge instead of just deleting - * @param cb function to call with the - * backend's return - * @param cb_cls closure for @a config_cb - * @return the instances handle; NULL upon error - */ -static struct TALER_MERCHANT_InstanceDeleteHandle * -instance_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - bool purge, - TALER_MERCHANT_InstanceDeleteCallback cb, - void *cb_cls) +struct TALER_MERCHANT_DeleteManagementInstanceHandle * +TALER_MERCHANT_delete_management_instance_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id) { - struct TALER_MERCHANT_InstanceDeleteHandle *idh; + struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih; - idh = GNUNET_new (struct TALER_MERCHANT_InstanceDeleteHandle); - idh->ctx = ctx; - idh->cb = cb; - idh->cb_cls = cb_cls; + dih = GNUNET_new (struct TALER_MERCHANT_DeleteManagementInstanceHandle); + dih->ctx = ctx; + dih->base_url = GNUNET_strdup (url); if (NULL != instance_id) + dih->instance_id = GNUNET_strdup (instance_id); + return dih; +} + + +void +TALER_MERCHANT_delete_management_instance_set_options_ ( + struct TALER_MERCHANT_DeleteManagementInstanceHandle *handle, + unsigned int num_options, + const struct TALER_MERCHANT_DeleteManagementInstanceOptionValue options[]) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_END: + return; + case TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_OPTION_PURGE: + handle->purge = true; + break; + } + } +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_management_instance_start ( + struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih, + TALER_MERCHANT_DeleteManagementInstanceCallback cb, + TALER_MERCHANT_DELETE_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls) +{ + CURL *eh; + + dih->cb = cb; + dih->cb_cls = cb_cls; + if (NULL != dih->instance_id) { char *path; GNUNET_asprintf (&path, "management/instances/%s", - instance_id); - idh->url = TALER_url_join (backend_url, + dih->instance_id); + dih->url = TALER_url_join (dih->base_url, path, "purge", - (purge) ? "yes" : NULL, + (dih->purge) ? "yes" : NULL, NULL); GNUNET_free (path); } else { /* backend_url is already identifying the instance */ - idh->url = TALER_url_join (backend_url, + dih->url = TALER_url_join (dih->base_url, "private", "purge", - (purge) ? "yes" : NULL, + (dih->purge) ? "yes" : NULL, NULL); } - if (NULL == idh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (idh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - idh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (idh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - idh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_instance_finished, - idh); - } - return idh; + if (NULL == dih->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dih->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dih->job = GNUNET_CURL_job_add (dih->ctx, + eh, + &handle_delete_instance_finished, + dih); + if (NULL == dih->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } -struct TALER_MERCHANT_InstanceDeleteHandle * -TALER_MERCHANT_instance_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceDeleteCallback cb, - void *cb_cls) -{ - return instance_delete (ctx, - backend_url, - instance_id, - false, - cb, - cb_cls); -} - - -struct TALER_MERCHANT_InstanceDeleteHandle * -TALER_MERCHANT_instance_purge (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceDeleteCallback cb, - void *cb_cls) +void +TALER_MERCHANT_delete_management_instance_cancel ( + struct TALER_MERCHANT_DeleteManagementInstanceHandle *dih) { - return instance_delete (ctx, - backend_url, - instance_id, - true, - cb, - cb_cls); + if (NULL != dih->job) + { + GNUNET_CURL_job_cancel (dih->job); + dih->job = NULL; + } + GNUNET_free (dih->url); + GNUNET_free (dih->instance_id); + GNUNET_free (dih->base_url); + GNUNET_free (dih); } -void -TALER_MERCHANT_instance_delete_cancel ( - struct TALER_MERCHANT_InstanceDeleteHandle *idh) -{ - if (NULL != idh->job) - GNUNET_CURL_job_cancel (idh->job); - GNUNET_free (idh->url); - GNUNET_free (idh); -} +/* end of merchant_api_delete-management-instances-INSTANCE-new.c */ diff --git a/src/lib/merchant_api_delete-private-accounts-H_WIRE-new.c b/src/lib/merchant_api_delete-private-accounts-H_WIRE-new.c @@ -1,204 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2023-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-accounts-H_WIRE-new.c - * @brief Implementation of the DELETE /private/accounts/$H_WIRE request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-accounts-H_WIRE-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/accounts/$H_WIRE operation. - */ -struct TALER_MERCHANT_DeletePrivateAccountHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateAccountCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Hash of the wire details identifying the account to delete. - */ - struct TALER_MerchantWireHashP h_wire; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/accounts/$H_WIRE request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateAccountHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_account_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateAccountHandle *dah = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateAccountResponse dar = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/accounts/$H_WIRE DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dar.hr.ec = TALER_JSON_get_error_code (json); - dar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dar.hr.ec = TALER_JSON_get_error_code (json); - dar.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dar.hr.ec = TALER_JSON_get_error_code (json); - dar.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/accounts/$H_WIRE\n", - (unsigned int) response_code, - (int) dar.hr.ec); - break; - } - dah->cb (dah->cb_cls, - &dar); - TALER_MERCHANT_delete_private_account_cancel (dah); -} - - -struct TALER_MERCHANT_DeletePrivateAccountHandle * -TALER_MERCHANT_delete_private_account_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_MerchantWireHashP *h_wire) -{ - struct TALER_MERCHANT_DeletePrivateAccountHandle *dah; - - dah = GNUNET_new (struct TALER_MERCHANT_DeletePrivateAccountHandle); - dah->ctx = ctx; - dah->base_url = GNUNET_strdup (url); - dah->h_wire = *h_wire; - return dah; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_account_start ( - struct TALER_MERCHANT_DeletePrivateAccountHandle *dah, - TALER_MERCHANT_DeletePrivateAccountCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dah->cb = cb; - dah->cb_cls = cb_cls; - { - char h_wire_str[sizeof (dah->h_wire) * 2]; - char *path; - char *end; - - end = GNUNET_STRINGS_data_to_string (&dah->h_wire, - sizeof (dah->h_wire), - h_wire_str, - sizeof (h_wire_str)); - *end = '\0'; - GNUNET_asprintf (&path, - "private/accounts/%s", - h_wire_str); - dah->url = TALER_url_join (dah->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == dah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dah->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dah->job = GNUNET_CURL_job_add (dah->ctx, - eh, - &handle_delete_account_finished, - dah); - if (NULL == dah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_account_cancel ( - struct TALER_MERCHANT_DeletePrivateAccountHandle *dah) -{ - if (NULL != dah->job) - { - GNUNET_CURL_job_cancel (dah->job); - dah->job = NULL; - } - GNUNET_free (dah->url); - GNUNET_free (dah->base_url); - GNUNET_free (dah); -} - - -/* end of merchant_api_delete-private-accounts-H_WIRE-new.c */ diff --git a/src/lib/merchant_api_delete-private-accounts-H_WIRE.c b/src/lib/merchant_api_delete-private-accounts-H_WIRE.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023 Taler Systems SA + Copyright (C) 2023-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-accounts-H_WIRE.c - * @brief Implementation of the DELETE /private/account/$H_WIRE request of the merchant's HTTP API + * @file merchant_api_delete-private-accounts-H_WIRE-new.c + * @brief Implementation of the DELETE /private/accounts/$H_WIRE request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-accounts-H_WIRE.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /accounts/$ID operation. + * Handle for a DELETE /private/accounts/$H_WIRE operation. */ -struct TALER_MERCHANT_AccountDeleteHandle +struct TALER_MERCHANT_DeletePrivateAccountHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_AccountDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_AccountDeleteCallback cb; + TALER_MERCHANT_DeletePrivateAccountCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Hash of the wire details identifying the account to delete. + */ + struct TALER_MerchantWireHashP h_wire; }; /** * Function called when we're done processing the - * HTTP DELETE /accounts/$H_WIRE request. + * HTTP DELETE /private/accounts/$H_WIRE request. * - * @param cls the `struct TALER_MERCHANT_AccountDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateAccountHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,109 +85,120 @@ handle_delete_account_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_AccountDeleteHandle *adh = cls; + struct TALER_MERCHANT_DeletePrivateAccountHandle *dah = cls; const json_t *json = response; - struct TALER_MERCHANT_AccountDeleteResponse adr = { + struct TALER_MERCHANT_DeletePrivateAccountResponse dar = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - adh->job = NULL; + dah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /accounts/$H_WIRE response with status code %u\n", + "Got /private/accounts/$H_WIRE DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - adr.hr.ec = TALER_JSON_get_error_code (json); - adr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dar.hr.ec = TALER_JSON_get_error_code (json); + dar.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: + dar.hr.ec = TALER_JSON_get_error_code (json); + dar.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - adr.hr.ec = TALER_JSON_get_error_code (json); - adr.hr.hint = TALER_JSON_get_error_hint (json); + dar.hr.ec = TALER_JSON_get_error_code (json); + dar.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /account/ID\n", + "Unexpected response code %u/%d for DELETE /private/accounts/$H_WIRE\n", (unsigned int) response_code, - (int) adr.hr.ec); + (int) dar.hr.ec); break; } - adh->cb (adh->cb_cls, - &adr); - TALER_MERCHANT_account_delete_cancel (adh); + dah->cb (dah->cb_cls, + &dar); + TALER_MERCHANT_delete_private_account_cancel (dah); } -struct TALER_MERCHANT_AccountDeleteHandle * -TALER_MERCHANT_account_delete ( +struct TALER_MERCHANT_DeletePrivateAccountHandle * +TALER_MERCHANT_delete_private_account_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MerchantWireHashP *h_wire, - TALER_MERCHANT_AccountDeleteCallback cb, - void *cb_cls) + const char *url, + const struct TALER_MerchantWireHashP *h_wire) +{ + struct TALER_MERCHANT_DeletePrivateAccountHandle *dah; + + dah = GNUNET_new (struct TALER_MERCHANT_DeletePrivateAccountHandle); + dah->ctx = ctx; + dah->base_url = GNUNET_strdup (url); + dah->h_wire = *h_wire; + return dah; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_account_start ( + struct TALER_MERCHANT_DeletePrivateAccountHandle *dah, + TALER_MERCHANT_DeletePrivateAccountCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_AccountDeleteHandle *adh; + CURL *eh; - adh = GNUNET_new (struct TALER_MERCHANT_AccountDeleteHandle); - adh->ctx = ctx; - adh->cb = cb; - adh->cb_cls = cb_cls; + dah->cb = cb; + dah->cb_cls = cb_cls; { - char h_wire_str[sizeof (*h_wire) * 2]; + char h_wire_str[sizeof (dah->h_wire) * 2]; char *path; char *end; - end = GNUNET_STRINGS_data_to_string (h_wire, - sizeof (*h_wire), + end = GNUNET_STRINGS_data_to_string (&dah->h_wire, + sizeof (dah->h_wire), h_wire_str, sizeof (h_wire_str)); *end = '\0'; GNUNET_asprintf (&path, - "private/account/%s", + "private/accounts/%s", h_wire_str); - adh->url = TALER_url_join (backend_url, + dah->url = TALER_url_join (dah->base_url, path, NULL); GNUNET_free (path); } - if (NULL == adh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (adh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - adh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (adh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - adh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_account_finished, - adh); - } - return adh; + if (NULL == dah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dah->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dah->job = GNUNET_CURL_job_add (dah->ctx, + eh, + &handle_delete_account_finished, + dah); + if (NULL == dah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_account_delete_cancel ( - struct TALER_MERCHANT_AccountDeleteHandle *adh) +TALER_MERCHANT_delete_private_account_cancel ( + struct TALER_MERCHANT_DeletePrivateAccountHandle *dah) { - if (NULL != adh->job) - GNUNET_CURL_job_cancel (adh->job); - GNUNET_free (adh->url); - GNUNET_free (adh); + if (NULL != dah->job) + { + GNUNET_CURL_job_cancel (dah->job); + dah->job = NULL; + } + GNUNET_free (dah->url); + GNUNET_free (dah->base_url); + GNUNET_free (dah); } + + +/* end of merchant_api_delete-private-accounts-H_WIRE-new.c */ diff --git a/src/lib/merchant_api_delete-private-donau-DONAU_SERIAL-new.c b/src/lib/merchant_api_delete-private-donau-DONAU_SERIAL-new.c @@ -1,194 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2024-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-donau-DONAU_SERIAL-new.c - * @brief Implementation of the DELETE /private/donau/$DONAU_SERIAL request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-donau-DONAU_SERIAL-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/donau/$DONAU_SERIAL operation. - */ -struct TALER_MERCHANT_DeletePrivateDonauHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateDonauCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Charity identifier to delete. - */ - uint64_t charity_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/donau/$DONAU_SERIAL request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateDonauHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_donau_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateDonauResponse ddr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ddh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/donau/$DONAU_SERIAL DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_NOT_FOUND: - case MHD_HTTP_UNAUTHORIZED: - ddr.hr.ec = TALER_JSON_get_error_code (json); - ddr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - ddr.hr.ec = TALER_JSON_get_error_code (json); - ddr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/donau/$DONAU_SERIAL\n", - (unsigned int) response_code, - (int) ddr.hr.ec); - break; - } - ddh->cb (ddh->cb_cls, - &ddr); - TALER_MERCHANT_delete_private_donau_cancel (ddh); -} - - -struct TALER_MERCHANT_DeletePrivateDonauHandle * -TALER_MERCHANT_delete_private_donau_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - uint64_t charity_id) -{ - struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh; - - ddh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateDonauHandle); - ddh->ctx = ctx; - ddh->base_url = GNUNET_strdup (url); - ddh->charity_id = charity_id; - return ddh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_donau_start ( - struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh, - TALER_MERCHANT_DeletePrivateDonauCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - ddh->cb = cb; - ddh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/donau/%llu", - (unsigned long long) ddh->charity_id); - ddh->url = TALER_url_join (ddh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == ddh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (ddh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - ddh->job = GNUNET_CURL_job_add (ddh->ctx, - eh, - &handle_delete_donau_finished, - ddh); - if (NULL == ddh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_donau_cancel ( - struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh) -{ - if (NULL != ddh->job) - { - GNUNET_CURL_job_cancel (ddh->job); - ddh->job = NULL; - } - GNUNET_free (ddh->url); - GNUNET_free (ddh->base_url); - GNUNET_free (ddh); -} - - -/* end of merchant_api_delete-private-donau-DONAU_SERIAL-new.c */ diff --git a/src/lib/merchant_api_delete-private-donau-DONAU_SERIAL.c b/src/lib/merchant_api_delete-private-donau-DONAU_SERIAL.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2024 Taler Systems SA + Copyright (C) 2024-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -11,38 +11,37 @@ A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> - */ - + TALER; see the file COPYING.LGPL. If not, see + <http://www.gnu.org/licenses/> +*/ /** - * @file merchant_api_delete-private-donau-DONAU_SERIAL.c - * @brief Implementation of the DELETE /donau/$charity_id request of the merchant's HTTP API - * @author Bohdan Potuzhnyi - * @author Vlada Svirsh + * @file merchant_api_delete-private-donau-DONAU_SERIAL-new.c + * @brief Implementation of the DELETE /private/donau/$DONAU_SERIAL request + * @author Christian Grothoff */ - #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-donau-DONAU_SERIAL.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> -/* DONAU RELATED IMPORTS */ -#include "taler/taler_merchant_donau.h" -#include <donau/donau_service.h> /** - * Handle for a DELETE /donau/$charity_id operation. + * Handle for a DELETE /private/donau/$DONAU_SERIAL operation. */ -struct TALER_MERCHANT_DonauInstanceDeleteHandle +struct TALER_MERCHANT_DeletePrivateDonauHandle { /** - * The URL for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -54,145 +53,142 @@ struct TALER_MERCHANT_DonauInstanceDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_DonauInstanceDeleteCallback cb; + TALER_MERCHANT_DeletePrivateDonauCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Charity identifier to delete. + */ + uint64_t charity_id; }; + /** * Function called when we're done processing the - * HTTP DELETE /donau/$charity_id request. + * HTTP DELETE /private/donau/$DONAU_SERIAL request. * - * @param cls the struct TALER_MERCHANT_DonauInstanceDeleteHandle + * @param cls the `struct TALER_MERCHANT_DeletePrivateDonauHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_delete_donau_instance_finished (void *cls, - long response_code, - const void *response) +handle_delete_donau_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_DonauInstanceDeleteHandle *ddh = cls; + struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateDonauResponse ddr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; ddh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /donau/$charity_id response with status code %u\n", + "Got /private/donau/$DONAU_SERIAL DELETE response with status code %u\n", (unsigned int) response_code); - switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_NOT_FOUND: case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ddr.hr.ec = TALER_JSON_get_error_code (json); + ddr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* Unexpected response */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ddr.hr.ec = TALER_JSON_get_error_code (json); + ddr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /donau/$charity_id\n", + "Unexpected response code %u/%d for DELETE /private/donau/$DONAU_SERIAL\n", (unsigned int) response_code, - (int) hr.ec); + (int) ddr.hr.ec); break; } ddh->cb (ddh->cb_cls, - &hr); - TALER_MERCHANT_donau_instance_delete_cancel (ddh); + &ddr); + TALER_MERCHANT_delete_private_donau_cancel (ddh); } -/** - * Initiates the DELETE /donau/$charity_id operation. - * - * @param ctx CURL context - * @param backend_url Base URL for the backend - * @param charity_id The ID of the charity to delete - * @param cb Callback function to handle the response - * @param cb_cls Closure for @a cb - * @return the handle for the operation, or NULL on error - */ -struct TALER_MERCHANT_DonauInstanceDeleteHandle * -TALER_MERCHANT_donau_instance_delete ( +struct TALER_MERCHANT_DeletePrivateDonauHandle * +TALER_MERCHANT_delete_private_donau_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - uint64_t charity_id, - TALER_MERCHANT_DonauInstanceDeleteCallback cb, - void *cb_cls) + const char *url, + uint64_t charity_id) { - struct TALER_MERCHANT_DonauInstanceDeleteHandle *ddh; - char *charity_id_str; - CURL *eh; - - GNUNET_asprintf (&charity_id_str, - "private/donau/%ld", - charity_id); - if (NULL == charity_id_str) - return NULL; + struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh; - ddh = GNUNET_new (struct TALER_MERCHANT_DonauInstanceDeleteHandle); + ddh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateDonauHandle); ddh->ctx = ctx; - ddh->cb = cb; - ddh->cb_cls = cb_cls; + ddh->base_url = GNUNET_strdup (url); + ddh->charity_id = charity_id; + return ddh; +} - ddh->url = TALER_url_join (backend_url, - charity_id_str, - NULL); - GNUNET_free (charity_id_str); - if (NULL == ddh->url) +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_donau_start ( + struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh, + TALER_MERCHANT_DeletePrivateDonauCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls) +{ + CURL *eh; + + ddh->cb = cb; + ddh->cb_cls = cb_cls; { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (ddh); - return NULL; + char *path; + + GNUNET_asprintf (&path, + "private/donau/%llu", + (unsigned long long) ddh->charity_id); + ddh->url = TALER_url_join (ddh->base_url, + path, + NULL); + GNUNET_free (path); } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - ddh->url); - + if (NULL == ddh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; eh = TALER_MERCHANT_curl_easy_get_ (ddh->url); - GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - "DELETE")); - ddh->job = GNUNET_CURL_job_add (ctx, + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + ddh->job = GNUNET_CURL_job_add (ddh->ctx, eh, - &handle_delete_donau_instance_finished, + &handle_delete_donau_finished, ddh); - - return ddh; + if (NULL == ddh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } -/** - * Cancel the DELETE /donau/$charity_id operation. - * - * @param ddh Handle for the operation to cancel. - */ void -TALER_MERCHANT_donau_instance_delete_cancel ( - struct TALER_MERCHANT_DonauInstanceDeleteHandle *ddh) +TALER_MERCHANT_delete_private_donau_cancel ( + struct TALER_MERCHANT_DeletePrivateDonauHandle *ddh) { if (NULL != ddh->job) + { GNUNET_CURL_job_cancel (ddh->job); - + ddh->job = NULL; + } GNUNET_free (ddh->url); + GNUNET_free (ddh->base_url); GNUNET_free (ddh); -} -\ No newline at end of file +} + + +/* end of merchant_api_delete-private-donau-DONAU_SERIAL-new.c */ diff --git a/src/lib/merchant_api_delete-private-orders-ORDER_ID-new.c b/src/lib/merchant_api_delete-private-orders-ORDER_ID-new.c @@ -1,230 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-orders-ORDER_ID-new.c - * @brief Implementation of the DELETE /private/orders/$ORDER_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-orders-ORDER_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/orders/$ORDER_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateOrderHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateOrderCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the order to delete. - */ - char *order_id; - - /** - * Whether to force deletion even if order has payments. - */ - bool force; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/orders/$ORDER_ID request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateOrderHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_order_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateOrderHandle *doh = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateOrderResponse dor = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - doh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/orders/$ORDER_ID DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/orders/$ORDER_ID\n", - (unsigned int) response_code, - (int) dor.hr.ec); - break; - } - doh->cb (doh->cb_cls, - &dor); - TALER_MERCHANT_delete_private_order_cancel (doh); -} - - -struct TALER_MERCHANT_DeletePrivateOrderHandle * -TALER_MERCHANT_delete_private_order_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id) -{ - struct TALER_MERCHANT_DeletePrivateOrderHandle *doh; - - doh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateOrderHandle); - doh->ctx = ctx; - doh->base_url = GNUNET_strdup (url); - doh->order_id = GNUNET_strdup (order_id); - doh->force = false; - return doh; -} - - -void -TALER_MERCHANT_delete_private_order_set_options_ ( - struct TALER_MERCHANT_DeletePrivateOrderHandle *handle, - unsigned int num_options, - const struct TALER_MERCHANT_DeletePrivateOrderOptionValue options[]) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_END: - return; - case TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_FORCE: - handle->force = true; - break; - } - } -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_order_start ( - struct TALER_MERCHANT_DeletePrivateOrderHandle *doh, - TALER_MERCHANT_DeletePrivateOrderCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - doh->cb = cb; - doh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/orders/%s", - doh->order_id); - doh->url = TALER_url_join (doh->base_url, - path, - "force", - (doh->force) ? "yes" : NULL, - NULL); - GNUNET_free (path); - } - if (NULL == doh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (doh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - doh->job = GNUNET_CURL_job_add (doh->ctx, - eh, - &handle_delete_order_finished, - doh); - if (NULL == doh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_order_cancel ( - struct TALER_MERCHANT_DeletePrivateOrderHandle *doh) -{ - if (NULL != doh->job) - { - GNUNET_CURL_job_cancel (doh->job); - doh->job = NULL; - } - GNUNET_free (doh->url); - GNUNET_free (doh->order_id); - GNUNET_free (doh->base_url); - GNUNET_free (doh); -} - - -/* end of merchant_api_delete-private-orders-ORDER_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-orders-ORDER_ID.c b/src/lib/merchant_api_delete-private-orders-ORDER_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2022 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-orders-ORDER_ID.c - * @brief Implementation of the DELETE /orders/$ORDER_ID request of the merchant's HTTP API - * @author Jonathan Buchanan + * @file merchant_api_delete-private-orders-ORDER_ID-new.c + * @brief Implementation of the DELETE /private/orders/$ORDER_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,18 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-orders-ORDER_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> + /** - * Handle for a DELETE /orders/$ID operation. + * Handle for a DELETE /private/orders/$ORDER_ID operation. */ -struct TALER_MERCHANT_OrderDeleteHandle +struct TALER_MERCHANT_DeletePrivateOrderHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -48,25 +53,35 @@ struct TALER_MERCHANT_OrderDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_OrderDeleteCallback cb; + TALER_MERCHANT_DeletePrivateOrderCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Identifier of the order to delete. + */ + char *order_id; + + /** + * Whether to force deletion even if order has payments. + */ + bool force; }; /** * Function called when we're done processing the - * HTTP DELETE /orders/$ORDER_ID request. + * HTTP DELETE /private/orders/$ORDER_ID request. * - * @param cls the `struct TALER_MERCHANT_OrderDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateOrderHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -75,103 +90,141 @@ handle_delete_order_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrderDeleteHandle *odh = cls; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = NULL, + struct TALER_MERCHANT_DeletePrivateOrderHandle *doh = cls; + const json_t *json = response; + struct TALER_MERCHANT_DeletePrivateOrderResponse dor = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - odh->job = NULL; + doh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /orders/$ID response with status code %u\n", + "Got /private/orders/$ORDER_ID DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (response); - hr.hint = TALER_JSON_get_error_hint (response); - /* Nothing really to verify, merchant says we need to authenticate. */ + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u\n", - (unsigned int) response_code); + "Unexpected response code %u/%d for DELETE /private/orders/$ORDER_ID\n", + (unsigned int) response_code, + (int) dor.hr.ec); break; } - odh->cb (odh->cb_cls, - &hr); - TALER_MERCHANT_order_delete_cancel (odh); + doh->cb (doh->cb_cls, + &dor); + TALER_MERCHANT_delete_private_order_cancel (doh); } -struct TALER_MERCHANT_OrderDeleteHandle * -TALER_MERCHANT_order_delete ( +struct TALER_MERCHANT_DeletePrivateOrderHandle * +TALER_MERCHANT_delete_private_order_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - bool force, - TALER_MERCHANT_OrderDeleteCallback cb, - void *cb_cls) + const char *url, + const char *order_id) +{ + struct TALER_MERCHANT_DeletePrivateOrderHandle *doh; + + doh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateOrderHandle); + doh->ctx = ctx; + doh->base_url = GNUNET_strdup (url); + doh->order_id = GNUNET_strdup (order_id); + doh->force = false; + return doh; +} + + +void +TALER_MERCHANT_delete_private_order_set_options_ ( + struct TALER_MERCHANT_DeletePrivateOrderHandle *handle, + unsigned int num_options, + const struct TALER_MERCHANT_DeletePrivateOrderOptionValue options[]) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_END: + return; + case TALER_MERCHANT_DELETE_PRIVATE_ORDER_OPTION_FORCE: + handle->force = true; + break; + } + } +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_order_start ( + struct TALER_MERCHANT_DeletePrivateOrderHandle *doh, + TALER_MERCHANT_DeletePrivateOrderCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderDeleteHandle *odh; + CURL *eh; - odh = GNUNET_new (struct TALER_MERCHANT_OrderDeleteHandle); - odh->ctx = ctx; - odh->cb = cb; - odh->cb_cls = cb_cls; + doh->cb = cb; + doh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, - "private/orders/%s%s", - order_id, - force - ? "?force=yes" - : ""); - - odh->url = TALER_url_join (backend_url, + "private/orders/%s", + doh->order_id); + doh->url = TALER_url_join (doh->base_url, path, + "force", + (doh->force) ? "yes" : NULL, NULL); GNUNET_free (path); } - if (NULL == odh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request url.\n"); - GNUNET_free (odh); - return NULL; - } - - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (odh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - odh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_order_finished, - odh); - } - return odh; + if (NULL == doh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (doh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + doh->job = GNUNET_CURL_job_add (doh->ctx, + eh, + &handle_delete_order_finished, + doh); + if (NULL == doh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_order_delete_cancel ( - struct TALER_MERCHANT_OrderDeleteHandle *odh) +TALER_MERCHANT_delete_private_order_cancel ( + struct TALER_MERCHANT_DeletePrivateOrderHandle *doh) { - if (NULL != odh->job) - GNUNET_CURL_job_cancel (odh->job); - GNUNET_free (odh->url); - GNUNET_free (odh); + if (NULL != doh->job) + { + GNUNET_CURL_job_cancel (doh->job); + doh->job = NULL; + } + GNUNET_free (doh->url); + GNUNET_free (doh->order_id); + GNUNET_free (doh->base_url); + GNUNET_free (doh); } + + +/* end of merchant_api_delete-private-orders-ORDER_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-otp-devices-DEVICE_ID-new.c b/src/lib/merchant_api_delete-private-otp-devices-DEVICE_ID-new.c @@ -1,202 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-otp-devices-DEVICE_ID-new.c - * @brief Implementation of the DELETE /private/otp-devices/$DEVICE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/otp-devices/$DEVICE_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateOtpDeviceCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the OTP device to delete. - */ - char *otp_device_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/otp-devices/$DEVICE_ID request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_otp_device_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateOtpDeviceResponse dor = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - doh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/otp-devices/$DEVICE_ID DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dor.hr.ec = TALER_JSON_get_error_code (json); - dor.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/otp-devices/$DEVICE_ID\n", - (unsigned int) response_code, - (int) dor.hr.ec); - break; - } - doh->cb (doh->cb_cls, - &dor); - TALER_MERCHANT_delete_private_otp_device_cancel (doh); -} - - -struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle * -TALER_MERCHANT_delete_private_otp_device_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id) -{ - struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh; - - doh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle); - doh->ctx = ctx; - doh->base_url = GNUNET_strdup (url); - doh->otp_device_id = GNUNET_strdup (otp_device_id); - return doh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_otp_device_start ( - struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh, - TALER_MERCHANT_DeletePrivateOtpDeviceCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - doh->cb = cb; - doh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/otp-devices/%s", - doh->otp_device_id); - doh->url = TALER_url_join (doh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == doh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (doh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - doh->job = GNUNET_CURL_job_add (doh->ctx, - eh, - &handle_delete_otp_device_finished, - doh); - if (NULL == doh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_otp_device_cancel ( - struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh) -{ - if (NULL != doh->job) - { - GNUNET_CURL_job_cancel (doh->job); - doh->job = NULL; - } - GNUNET_free (doh->url); - GNUNET_free (doh->otp_device_id); - GNUNET_free (doh->base_url); - GNUNET_free (doh); -} - - -/* end of merchant_api_delete-private-otp-devices-DEVICE_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-otp-devices-DEVICE_ID.c b/src/lib/merchant_api_delete-private-otp-devices-DEVICE_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-otp-devices-DEVICE_ID.c - * @brief Implementation of the DELETE /otp-devices/$ID request of the merchant's HTTP API + * @file merchant_api_delete-private-otp-devices-DEVICE_ID-new.c + * @brief Implementation of the DELETE /private/otp-devices/$DEVICE_ID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /otp-devices/$ID operation. + * Handle for a DELETE /private/otp-devices/$DEVICE_ID operation. */ -struct TALER_MERCHANT_OtpDeviceDeleteHandle +struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_OtpDeviceDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_OtpDeviceDeleteCallback cb; + TALER_MERCHANT_DeletePrivateOtpDeviceCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Identifier of the OTP device to delete. + */ + char *otp_device_id; }; /** * Function called when we're done processing the - * HTTP GET /otp-devices/$ID request. + * HTTP DELETE /private/otp-devices/$DEVICE_ID request. * - * @param cls the `struct TALER_MERCHANT_OtpDeviceDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,108 +85,118 @@ handle_delete_otp_device_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OtpDeviceDeleteHandle *tdh = cls; + struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateOtpDeviceResponse dor = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tdh->job = NULL; + doh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got DELETE /otp-devices/$ID response with status code %u\n", + "Got /private/otp-devices/$DEVICE_ID DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dor.hr.ec = TALER_JSON_get_error_code (json); + dor.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", + "Unexpected response code %u/%d for DELETE /private/otp-devices/$DEVICE_ID\n", (unsigned int) response_code, - (int) hr.ec); + (int) dor.hr.ec); break; } - tdh->cb (tdh->cb_cls, - &hr); - TALER_MERCHANT_otp_device_delete_cancel (tdh); + doh->cb (doh->cb_cls, + &dor); + TALER_MERCHANT_delete_private_otp_device_cancel (doh); } -struct TALER_MERCHANT_OtpDeviceDeleteHandle * -TALER_MERCHANT_otp_device_delete ( +struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle * +TALER_MERCHANT_delete_private_otp_device_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *otp_device_id, - TALER_MERCHANT_OtpDeviceDeleteCallback cb, - void *cb_cls) + const char *url, + const char *otp_device_id) +{ + struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh; + + doh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle); + doh->ctx = ctx; + doh->base_url = GNUNET_strdup (url); + doh->otp_device_id = GNUNET_strdup (otp_device_id); + return doh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_otp_device_start ( + struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh, + TALER_MERCHANT_DeletePrivateOtpDeviceCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OtpDeviceDeleteHandle *tdh; + CURL *eh; - tdh = GNUNET_new (struct TALER_MERCHANT_OtpDeviceDeleteHandle); - tdh->ctx = ctx; - tdh->cb = cb; - tdh->cb_cls = cb_cls; + doh->cb = cb; + doh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/otp-devices/%s", - otp_device_id); - tdh->url = TALER_url_join (backend_url, + doh->otp_device_id); + doh->url = TALER_url_join (doh->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tdh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tdh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tdh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tdh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - tdh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_otp_device_finished, - tdh); - } - return tdh; + if (NULL == doh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (doh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + doh->job = GNUNET_CURL_job_add (doh->ctx, + eh, + &handle_delete_otp_device_finished, + doh); + if (NULL == doh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_otp_device_delete_cancel ( - struct TALER_MERCHANT_OtpDeviceDeleteHandle *tdh) +TALER_MERCHANT_delete_private_otp_device_cancel ( + struct TALER_MERCHANT_DeletePrivateOtpDeviceHandle *doh) { - if (NULL != tdh->job) - GNUNET_CURL_job_cancel (tdh->job); - GNUNET_free (tdh->url); - GNUNET_free (tdh); + if (NULL != doh->job) + { + GNUNET_CURL_job_cancel (doh->job); + doh->job = NULL; + } + GNUNET_free (doh->url); + GNUNET_free (doh->otp_device_id); + GNUNET_free (doh->base_url); + GNUNET_free (doh); } + + +/* end of merchant_api_delete-private-otp-devices-DEVICE_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-products-PRODUCT_ID-new.c b/src/lib/merchant_api_delete-private-products-PRODUCT_ID-new.c @@ -1,202 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-products-PRODUCT_ID-new.c - * @brief Implementation of the DELETE /private/products/$PRODUCT_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/products/$PRODUCT_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateProductHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateProductCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the product to delete. - */ - char *product_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/products/$PRODUCT_ID request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateProductHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_product_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateProductHandle *dph = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateProductResponse dpr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/products/$PRODUCT_ID DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dpr.hr.ec = TALER_JSON_get_error_code (json); - dpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dpr.hr.ec = TALER_JSON_get_error_code (json); - dpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dpr.hr.ec = TALER_JSON_get_error_code (json); - dpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dpr.hr.ec = TALER_JSON_get_error_code (json); - dpr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/products/$PRODUCT_ID\n", - (unsigned int) response_code, - (int) dpr.hr.ec); - break; - } - dph->cb (dph->cb_cls, - &dpr); - TALER_MERCHANT_delete_private_product_cancel (dph); -} - - -struct TALER_MERCHANT_DeletePrivateProductHandle * -TALER_MERCHANT_delete_private_product_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id) -{ - struct TALER_MERCHANT_DeletePrivateProductHandle *dph; - - dph = GNUNET_new (struct TALER_MERCHANT_DeletePrivateProductHandle); - dph->ctx = ctx; - dph->base_url = GNUNET_strdup (url); - dph->product_id = GNUNET_strdup (product_id); - return dph; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_product_start ( - struct TALER_MERCHANT_DeletePrivateProductHandle *dph, - TALER_MERCHANT_DeletePrivateProductCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dph->cb = cb; - dph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/products/%s", - dph->product_id); - dph->url = TALER_url_join (dph->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == dph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dph->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dph->job = GNUNET_CURL_job_add (dph->ctx, - eh, - &handle_delete_product_finished, - dph); - if (NULL == dph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_product_cancel ( - struct TALER_MERCHANT_DeletePrivateProductHandle *dph) -{ - if (NULL != dph->job) - { - GNUNET_CURL_job_cancel (dph->job); - dph->job = NULL; - } - GNUNET_free (dph->url); - GNUNET_free (dph->product_id); - GNUNET_free (dph->base_url); - GNUNET_free (dph); -} - - -/* end of merchant_api_delete-private-products-PRODUCT_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-products-PRODUCT_ID.c b/src/lib/merchant_api_delete-private-products-PRODUCT_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018, 2020 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-products-PRODUCT_ID.c - * @brief Implementation of the DELETE /product/$ID request of the merchant's HTTP API + * @file merchant_api_delete-private-products-PRODUCT_ID-new.c + * @brief Implementation of the DELETE /private/products/$PRODUCT_ID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-products-PRODUCT_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /products/$ID operation. + * Handle for a DELETE /private/products/$PRODUCT_ID operation. */ -struct TALER_MERCHANT_ProductDeleteHandle +struct TALER_MERCHANT_DeletePrivateProductHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_ProductDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductDeleteCallback cb; + TALER_MERCHANT_DeletePrivateProductCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Identifier of the product to delete. + */ + char *product_id; }; /** * Function called when we're done processing the - * HTTP GET /products/$ID request. + * HTTP DELETE /private/products/$PRODUCT_ID request. * - * @param cls the `struct TALER_MERCHANT_ProductDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateProductHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,108 +85,118 @@ handle_delete_product_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_ProductDeleteHandle *pdh = cls; + struct TALER_MERCHANT_DeletePrivateProductHandle *dph = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateProductResponse dpr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - pdh->job = NULL; + dph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /products/$ID response with status code %u\n", + "Got /private/products/$PRODUCT_ID DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dpr.hr.ec = TALER_JSON_get_error_code (json); + dpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dpr.hr.ec = TALER_JSON_get_error_code (json); + dpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dpr.hr.ec = TALER_JSON_get_error_code (json); + dpr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dpr.hr.ec = TALER_JSON_get_error_code (json); + dpr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", + "Unexpected response code %u/%d for DELETE /private/products/$PRODUCT_ID\n", (unsigned int) response_code, - (int) hr.ec); + (int) dpr.hr.ec); break; } - pdh->cb (pdh->cb_cls, - &hr); - TALER_MERCHANT_product_delete_cancel (pdh); + dph->cb (dph->cb_cls, + &dpr); + TALER_MERCHANT_delete_private_product_cancel (dph); } -struct TALER_MERCHANT_ProductDeleteHandle * -TALER_MERCHANT_product_delete ( +struct TALER_MERCHANT_DeletePrivateProductHandle * +TALER_MERCHANT_delete_private_product_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - TALER_MERCHANT_ProductDeleteCallback cb, - void *cb_cls) + const char *url, + const char *product_id) +{ + struct TALER_MERCHANT_DeletePrivateProductHandle *dph; + + dph = GNUNET_new (struct TALER_MERCHANT_DeletePrivateProductHandle); + dph->ctx = ctx; + dph->base_url = GNUNET_strdup (url); + dph->product_id = GNUNET_strdup (product_id); + return dph; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_product_start ( + struct TALER_MERCHANT_DeletePrivateProductHandle *dph, + TALER_MERCHANT_DeletePrivateProductCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ProductDeleteHandle *pdh; + CURL *eh; - pdh = GNUNET_new (struct TALER_MERCHANT_ProductDeleteHandle); - pdh->ctx = ctx; - pdh->cb = cb; - pdh->cb_cls = cb_cls; + dph->cb = cb; + dph->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/products/%s", - product_id); - pdh->url = TALER_url_join (backend_url, + dph->product_id); + dph->url = TALER_url_join (dph->base_url, path, NULL); GNUNET_free (path); } - if (NULL == pdh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (pdh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - pdh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (pdh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - pdh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_product_finished, - pdh); - } - return pdh; + if (NULL == dph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dph->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dph->job = GNUNET_CURL_job_add (dph->ctx, + eh, + &handle_delete_product_finished, + dph); + if (NULL == dph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_product_delete_cancel ( - struct TALER_MERCHANT_ProductDeleteHandle *pdh) +TALER_MERCHANT_delete_private_product_cancel ( + struct TALER_MERCHANT_DeletePrivateProductHandle *dph) { - if (NULL != pdh->job) - GNUNET_CURL_job_cancel (pdh->job); - GNUNET_free (pdh->url); - GNUNET_free (pdh); + if (NULL != dph->job) + { + GNUNET_CURL_job_cancel (dph->job); + dph->job = NULL; + } + GNUNET_free (dph->url); + GNUNET_free (dph->product_id); + GNUNET_free (dph->base_url); + GNUNET_free (dph); } + + +/* end of merchant_api_delete-private-products-PRODUCT_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-templates-TEMPLATE_ID-new.c b/src/lib/merchant_api_delete-private-templates-TEMPLATE_ID-new.c @@ -1,202 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-templates-TEMPLATE_ID-new.c - * @brief Implementation of the DELETE /private/templates/$TEMPLATE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/templates/$TEMPLATE_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateTemplateHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateTemplateCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the template to delete. - */ - char *template_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/templates/$TEMPLATE_ID request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateTemplateHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_template_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateTemplateResponse dtr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/templates/$TEMPLATE_ID DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/templates/$TEMPLATE_ID\n", - (unsigned int) response_code, - (int) dtr.hr.ec); - break; - } - dth->cb (dth->cb_cls, - &dtr); - TALER_MERCHANT_delete_private_template_cancel (dth); -} - - -struct TALER_MERCHANT_DeletePrivateTemplateHandle * -TALER_MERCHANT_delete_private_template_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id) -{ - struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth; - - dth = GNUNET_new (struct TALER_MERCHANT_DeletePrivateTemplateHandle); - dth->ctx = ctx; - dth->base_url = GNUNET_strdup (url); - dth->template_id = GNUNET_strdup (template_id); - return dth; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_template_start ( - struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth, - TALER_MERCHANT_DeletePrivateTemplateCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dth->cb = cb; - dth->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/templates/%s", - dth->template_id); - dth->url = TALER_url_join (dth->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == dth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dth->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dth->job = GNUNET_CURL_job_add (dth->ctx, - eh, - &handle_delete_template_finished, - dth); - if (NULL == dth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_template_cancel ( - struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth) -{ - if (NULL != dth->job) - { - GNUNET_CURL_job_cancel (dth->job); - dth->job = NULL; - } - GNUNET_free (dth->url); - GNUNET_free (dth->template_id); - GNUNET_free (dth->base_url); - GNUNET_free (dth); -} - - -/* end of merchant_api_delete-private-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-templates-TEMPLATE_ID.c b/src/lib/merchant_api_delete-private-templates-TEMPLATE_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-templates-TEMPLATE_ID.c - * @brief Implementation of the DELETE /templates/$ID request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_delete-private-templates-TEMPLATE_ID-new.c + * @brief Implementation of the DELETE /private/templates/$TEMPLATE_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /templates/$ID operation. + * Handle for a DELETE /private/templates/$TEMPLATE_ID operation. */ -struct TALER_MERCHANT_TemplateDeleteHandle +struct TALER_MERCHANT_DeletePrivateTemplateHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_TemplateDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_TemplateDeleteCallback cb; + TALER_MERCHANT_DeletePrivateTemplateCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Identifier of the template to delete. + */ + char *template_id; }; /** * Function called when we're done processing the - * HTTP GET /templates/$ID request. + * HTTP DELETE /private/templates/$TEMPLATE_ID request. * - * @param cls the `struct TALER_MERCHANT_TemplateDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateTemplateHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,108 +85,118 @@ handle_delete_template_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TemplateDeleteHandle *tdh = cls; + struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateTemplateResponse dtr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tdh->job = NULL; + dth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /templates/$ID response with status code %u\n", + "Got /private/templates/$TEMPLATE_ID DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", + "Unexpected response code %u/%d for DELETE /private/templates/$TEMPLATE_ID\n", (unsigned int) response_code, - (int) hr.ec); + (int) dtr.hr.ec); break; } - tdh->cb (tdh->cb_cls, - &hr); - TALER_MERCHANT_template_delete_cancel (tdh); + dth->cb (dth->cb_cls, + &dtr); + TALER_MERCHANT_delete_private_template_cancel (dth); } -struct TALER_MERCHANT_TemplateDeleteHandle * -TALER_MERCHANT_template_delete ( +struct TALER_MERCHANT_DeletePrivateTemplateHandle * +TALER_MERCHANT_delete_private_template_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - TALER_MERCHANT_TemplateDeleteCallback cb, - void *cb_cls) + const char *url, + const char *template_id) +{ + struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth; + + dth = GNUNET_new (struct TALER_MERCHANT_DeletePrivateTemplateHandle); + dth->ctx = ctx; + dth->base_url = GNUNET_strdup (url); + dth->template_id = GNUNET_strdup (template_id); + return dth; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_template_start ( + struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth, + TALER_MERCHANT_DeletePrivateTemplateCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TemplateDeleteHandle *tdh; + CURL *eh; - tdh = GNUNET_new (struct TALER_MERCHANT_TemplateDeleteHandle); - tdh->ctx = ctx; - tdh->cb = cb; - tdh->cb_cls = cb_cls; + dth->cb = cb; + dth->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/templates/%s", - template_id); - tdh->url = TALER_url_join (backend_url, + dth->template_id); + dth->url = TALER_url_join (dth->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tdh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tdh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tdh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tdh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - tdh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_template_finished, - tdh); - } - return tdh; + if (NULL == dth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dth->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dth->job = GNUNET_CURL_job_add (dth->ctx, + eh, + &handle_delete_template_finished, + dth); + if (NULL == dth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_template_delete_cancel ( - struct TALER_MERCHANT_TemplateDeleteHandle *tdh) +TALER_MERCHANT_delete_private_template_cancel ( + struct TALER_MERCHANT_DeletePrivateTemplateHandle *dth) { - if (NULL != tdh->job) - GNUNET_CURL_job_cancel (tdh->job); - GNUNET_free (tdh->url); - GNUNET_free (tdh); + if (NULL != dth->job) + { + GNUNET_CURL_job_cancel (dth->job); + dth->job = NULL; + } + GNUNET_free (dth->url); + GNUNET_free (dth->template_id); + GNUNET_free (dth->base_url); + GNUNET_free (dth); } + + +/* end of merchant_api_delete-private-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-tokens-SERIAL-new.c b/src/lib/merchant_api_delete-private-tokens-SERIAL-new.c @@ -1,198 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-tokens-SERIAL-new.c - * @brief Implementation of the DELETE /private/tokens/$SERIAL request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-tokens-SERIAL-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/tokens/$SERIAL operation. - */ -struct TALER_MERCHANT_DeletePrivateTokenHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateTokenCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the instance whose token to delete. - */ - char *instance_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/tokens/$SERIAL request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateTokenHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_token_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateTokenHandle *dth = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateTokenResponse dtr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got DELETE /instances/$ID/private/token response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /instances/$ID/private/token\n", - (unsigned int) response_code, - (int) dtr.hr.ec); - break; - } - dth->cb (dth->cb_cls, - &dtr); - TALER_MERCHANT_delete_private_token_cancel (dth); -} - - -struct TALER_MERCHANT_DeletePrivateTokenHandle * -TALER_MERCHANT_delete_private_token_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id) -{ - struct TALER_MERCHANT_DeletePrivateTokenHandle *dth; - - dth = GNUNET_new (struct TALER_MERCHANT_DeletePrivateTokenHandle); - dth->ctx = ctx; - dth->base_url = GNUNET_strdup (url); - dth->instance_id = GNUNET_strdup (instance_id); - return dth; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_token_start ( - struct TALER_MERCHANT_DeletePrivateTokenHandle *dth, - TALER_MERCHANT_DeletePrivateTokenCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dth->cb = cb; - dth->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "instances/%s/private/token", - dth->instance_id); - dth->url = TALER_url_join (dth->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == dth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dth->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dth->job = GNUNET_CURL_job_add (dth->ctx, - eh, - &handle_delete_token_finished, - dth); - if (NULL == dth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_token_cancel ( - struct TALER_MERCHANT_DeletePrivateTokenHandle *dth) -{ - if (NULL != dth->job) - { - GNUNET_CURL_job_cancel (dth->job); - dth->job = NULL; - } - GNUNET_free (dth->url); - GNUNET_free (dth->instance_id); - GNUNET_free (dth->base_url); - GNUNET_free (dth); -} - - -/* end of merchant_api_delete-private-tokens-SERIAL-new.c */ diff --git a/src/lib/merchant_api_delete-private-tokens-SERIAL.c b/src/lib/merchant_api_delete-private-tokens-SERIAL.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-tokens-SERIAL.c - * @brief Implementation of the DELETE /instance/$ID/private/token request of the merchant's HTTP API - * @author Martin Schanzenbach + * @file merchant_api_delete-private-tokens-SERIAL-new.c + * @brief Implementation of the DELETE /private/tokens/$SERIAL request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-tokens-SERIAL.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /instance/$ID/private/token operation. + * Handle for a DELETE /private/tokens/$SERIAL operation. */ -struct TALER_MERCHANT_InstanceTokenDeleteHandle +struct TALER_MERCHANT_DeletePrivateTokenHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_InstanceTokenDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstanceTokenDeleteCallback cb; + TALER_MERCHANT_DeletePrivateTokenCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Identifier of the instance whose token to delete. + */ + char *instance_id; }; /** * Function called when we're done processing the - * HTTP DELETE /instance/$ID/private/token request. + * HTTP DELETE /private/tokens/$SERIAL request. * - * @param cls the `struct TALER_MERCHANT_TokenDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateTokenHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,102 +85,114 @@ handle_delete_token_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_InstanceTokenDeleteHandle *tdh = cls; + struct TALER_MERCHANT_DeletePrivateTokenHandle *dth = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse tdr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateTokenResponse dtr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tdh->job = NULL; + dth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /instances/$ID/private/token response with status code %u\n", + "Got DELETE /instances/$ID/private/token response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - tdr.ec = TALER_JSON_get_error_code (json); - tdr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - tdr.ec = TALER_JSON_get_error_code (json); - tdr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /instance/$ID/private/token\n", + "Unexpected response code %u/%d for DELETE /instances/$ID/private/token\n", (unsigned int) response_code, - (int) tdr.ec); + (int) dtr.hr.ec); break; } - tdh->cb (tdh->cb_cls, - &tdr); - TALER_MERCHANT_instance_token_delete_cancel (tdh); + dth->cb (dth->cb_cls, + &dtr); + TALER_MERCHANT_delete_private_token_cancel (dth); } -struct TALER_MERCHANT_InstanceTokenDeleteHandle * -TALER_MERCHANT_instance_token_delete ( +struct TALER_MERCHANT_DeletePrivateTokenHandle * +TALER_MERCHANT_delete_private_token_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceTokenDeleteCallback cb, - void *cb_cls) + const char *url, + const char *instance_id) +{ + struct TALER_MERCHANT_DeletePrivateTokenHandle *dth; + + dth = GNUNET_new (struct TALER_MERCHANT_DeletePrivateTokenHandle); + dth->ctx = ctx; + dth->base_url = GNUNET_strdup (url); + dth->instance_id = GNUNET_strdup (instance_id); + return dth; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_token_start ( + struct TALER_MERCHANT_DeletePrivateTokenHandle *dth, + TALER_MERCHANT_DeletePrivateTokenCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_InstanceTokenDeleteHandle *tdh; + CURL *eh; - tdh = GNUNET_new (struct TALER_MERCHANT_InstanceTokenDeleteHandle); - tdh->ctx = ctx; - tdh->cb = cb; - tdh->cb_cls = cb_cls; + dth->cb = cb; + dth->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "instances/%s/private/token", - instance_id); - tdh->url = TALER_url_join (backend_url, + dth->instance_id); + dth->url = TALER_url_join (dth->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tdh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tdh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tdh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tdh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - tdh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_token_finished, - tdh); - } - return tdh; + if (NULL == dth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dth->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dth->job = GNUNET_CURL_job_add (dth->ctx, + eh, + &handle_delete_token_finished, + dth); + if (NULL == dth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instance_token_delete_cancel ( - struct TALER_MERCHANT_InstanceTokenDeleteHandle *tdh) +TALER_MERCHANT_delete_private_token_cancel ( + struct TALER_MERCHANT_DeletePrivateTokenHandle *dth) { - if (NULL != tdh->job) - GNUNET_CURL_job_cancel (tdh->job); - GNUNET_free (tdh->url); - GNUNET_free (tdh); + if (NULL != dth->job) + { + GNUNET_CURL_job_cancel (dth->job); + dth->job = NULL; + } + GNUNET_free (dth->url); + GNUNET_free (dth->instance_id); + GNUNET_free (dth->base_url); + GNUNET_free (dth); } + + +/* end of merchant_api_delete-private-tokens-SERIAL-new.c */ diff --git a/src/lib/merchant_api_delete-private-transfers-TID-new.c b/src/lib/merchant_api_delete-private-transfers-TID-new.c @@ -1,201 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2021-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-transfers-TID-new.c - * @brief Implementation of the DELETE /private/transfers/$TID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-transfers-TID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/transfers/$TID operation. - */ -struct TALER_MERCHANT_DeletePrivateTransferHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateTransferCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Serial number of the wire transfer to delete. - */ - uint64_t wire_transfer_serial; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/transfers/$TID request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateTransferHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_transfer_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateTransferHandle *dth = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateTransferResponse dtr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/transfers/$TID DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dtr.hr.ec = TALER_JSON_get_error_code (json); - dtr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/transfers/$TID\n", - (unsigned int) response_code, - (int) dtr.hr.ec); - break; - } - dth->cb (dth->cb_cls, - &dtr); - TALER_MERCHANT_delete_private_transfer_cancel (dth); -} - - -struct TALER_MERCHANT_DeletePrivateTransferHandle * -TALER_MERCHANT_delete_private_transfer_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - uint64_t wire_transfer_serial) -{ - struct TALER_MERCHANT_DeletePrivateTransferHandle *dth; - - dth = GNUNET_new (struct TALER_MERCHANT_DeletePrivateTransferHandle); - dth->ctx = ctx; - dth->base_url = GNUNET_strdup (url); - dth->wire_transfer_serial = wire_transfer_serial; - return dth; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_transfer_start ( - struct TALER_MERCHANT_DeletePrivateTransferHandle *dth, - TALER_MERCHANT_DeletePrivateTransferCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dth->cb = cb; - dth->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/transfers/%llu", - (unsigned long long) dth->wire_transfer_serial); - dth->url = TALER_url_join (dth->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == dth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dth->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dth->job = GNUNET_CURL_job_add (dth->ctx, - eh, - &handle_delete_transfer_finished, - dth); - if (NULL == dth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_transfer_cancel ( - struct TALER_MERCHANT_DeletePrivateTransferHandle *dth) -{ - if (NULL != dth->job) - { - GNUNET_CURL_job_cancel (dth->job); - dth->job = NULL; - } - GNUNET_free (dth->url); - GNUNET_free (dth->base_url); - GNUNET_free (dth); -} - - -/* end of merchant_api_delete-private-transfers-TID-new.c */ diff --git a/src/lib/merchant_api_delete-private-transfers-TID.c b/src/lib/merchant_api_delete-private-transfers-TID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2021 Taler Systems SA + Copyright (C) 2021-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-transfers-TID.c - * @brief Implementation of the DELETE /transfer/$ID request of the merchant's HTTP API + * @file merchant_api_delete-private-transfers-TID-new.c + * @brief Implementation of the DELETE /private/transfers/$TID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-transfers-TID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /transfers/$ID operation. + * Handle for a DELETE /private/transfers/$TID operation. */ -struct TALER_MERCHANT_TransferDeleteHandle +struct TALER_MERCHANT_DeletePrivateTransferHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_TransferDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_TransferDeleteCallback cb; + TALER_MERCHANT_DeletePrivateTransferCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Serial number of the wire transfer to delete. + */ + uint64_t wire_transfer_serial; }; /** * Function called when we're done processing the - * HTTP GET /transfers/$ID request. + * HTTP DELETE /private/transfers/$TID request. * - * @param cls the `struct TALER_MERCHANT_TransferDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateTransferHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,108 +85,117 @@ handle_delete_transfer_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TransferDeleteHandle *tdh = cls; + struct TALER_MERCHANT_DeletePrivateTransferHandle *dth = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateTransferResponse dtr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tdh->job = NULL; + dth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /transfers/$ID response with status code %u\n", + "Got /private/transfers/$TID DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dtr.hr.ec = TALER_JSON_get_error_code (json); + dtr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", + "Unexpected response code %u/%d for DELETE /private/transfers/$TID\n", (unsigned int) response_code, - (int) hr.ec); + (int) dtr.hr.ec); break; } - tdh->cb (tdh->cb_cls, - &hr); - TALER_MERCHANT_transfer_delete_cancel (tdh); + dth->cb (dth->cb_cls, + &dtr); + TALER_MERCHANT_delete_private_transfer_cancel (dth); } -struct TALER_MERCHANT_TransferDeleteHandle * -TALER_MERCHANT_transfer_delete ( +struct TALER_MERCHANT_DeletePrivateTransferHandle * +TALER_MERCHANT_delete_private_transfer_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - uint64_t wire_transfer_serial, - TALER_MERCHANT_TransferDeleteCallback cb, - void *cb_cls) + const char *url, + uint64_t wire_transfer_serial) +{ + struct TALER_MERCHANT_DeletePrivateTransferHandle *dth; + + dth = GNUNET_new (struct TALER_MERCHANT_DeletePrivateTransferHandle); + dth->ctx = ctx; + dth->base_url = GNUNET_strdup (url); + dth->wire_transfer_serial = wire_transfer_serial; + return dth; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_transfer_start ( + struct TALER_MERCHANT_DeletePrivateTransferHandle *dth, + TALER_MERCHANT_DeletePrivateTransferCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_TRANSFER_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TransferDeleteHandle *tdh; + CURL *eh; - tdh = GNUNET_new (struct TALER_MERCHANT_TransferDeleteHandle); - tdh->ctx = ctx; - tdh->cb = cb; - tdh->cb_cls = cb_cls; + dth->cb = cb; + dth->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/transfers/%llu", - (unsigned long long) wire_transfer_serial); - tdh->url = TALER_url_join (backend_url, + (unsigned long long) dth->wire_transfer_serial); + dth->url = TALER_url_join (dth->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tdh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tdh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tdh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tdh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - tdh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_transfer_finished, - tdh); - } - return tdh; + if (NULL == dth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dth->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dth->job = GNUNET_CURL_job_add (dth->ctx, + eh, + &handle_delete_transfer_finished, + dth); + if (NULL == dth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_transfer_delete_cancel ( - struct TALER_MERCHANT_TransferDeleteHandle *tdh) +TALER_MERCHANT_delete_private_transfer_cancel ( + struct TALER_MERCHANT_DeletePrivateTransferHandle *dth) { - if (NULL != tdh->job) - GNUNET_CURL_job_cancel (tdh->job); - GNUNET_free (tdh->url); - GNUNET_free (tdh); + if (NULL != dth->job) + { + GNUNET_CURL_job_cancel (dth->job); + dth->job = NULL; + } + GNUNET_free (dth->url); + GNUNET_free (dth->base_url); + GNUNET_free (dth); } + + +/* end of merchant_api_delete-private-transfers-TID-new.c */ diff --git a/src/lib/merchant_api_delete-private-units-UNIT-new.c b/src/lib/merchant_api_delete-private-units-UNIT-new.c @@ -1,202 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-units-UNIT-new.c - * @brief Implementation of the DELETE /private/units/$UNIT request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-units-UNIT-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/units/$UNIT operation. - */ -struct TALER_MERCHANT_DeletePrivateUnitHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateUnitCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the unit to delete. - */ - char *unit_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/units/$UNIT request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateUnitHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_unit_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateUnitHandle *duh = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateUnitResponse dur = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - duh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/units/$UNIT DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dur.hr.ec = TALER_JSON_get_error_code (json); - dur.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - dur.hr.ec = TALER_JSON_get_error_code (json); - dur.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dur.hr.ec = TALER_JSON_get_error_code (json); - dur.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dur.hr.ec = TALER_JSON_get_error_code (json); - dur.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/units/$UNIT\n", - (unsigned int) response_code, - (int) dur.hr.ec); - break; - } - duh->cb (duh->cb_cls, - &dur); - TALER_MERCHANT_delete_private_unit_cancel (duh); -} - - -struct TALER_MERCHANT_DeletePrivateUnitHandle * -TALER_MERCHANT_delete_private_unit_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *unit_id) -{ - struct TALER_MERCHANT_DeletePrivateUnitHandle *duh; - - duh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateUnitHandle); - duh->ctx = ctx; - duh->base_url = GNUNET_strdup (url); - duh->unit_id = GNUNET_strdup (unit_id); - return duh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_unit_start ( - struct TALER_MERCHANT_DeletePrivateUnitHandle *duh, - TALER_MERCHANT_DeletePrivateUnitCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - duh->cb = cb; - duh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/units/%s", - duh->unit_id); - duh->url = TALER_url_join (duh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == duh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (duh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - duh->job = GNUNET_CURL_job_add (duh->ctx, - eh, - &handle_delete_unit_finished, - duh); - if (NULL == duh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_unit_cancel ( - struct TALER_MERCHANT_DeletePrivateUnitHandle *duh) -{ - if (NULL != duh->job) - { - GNUNET_CURL_job_cancel (duh->job); - duh->job = NULL; - } - GNUNET_free (duh->url); - GNUNET_free (duh->unit_id); - GNUNET_free (duh->base_url); - GNUNET_free (duh); -} - - -/* end of merchant_api_delete-private-units-UNIT-new.c */ diff --git a/src/lib/merchant_api_delete-private-units-UNIT.c b/src/lib/merchant_api_delete-private-units-UNIT.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -11,167 +11,192 @@ A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> + TALER; see the file COPYING.LGPL. If not, see + <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-units-UNIT.c - * @brief Implementation of DELETE /private/units/$ID - * @author Bohdan Potuzhnyi + * @file merchant_api_delete-private-units-UNIT-new.c + * @brief Implementation of the DELETE /private/units/$UNIT request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-units-UNIT.h> #include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" #include <taler/taler_json_lib.h> /** - * Handle for a DELETE /private/units/$ID operation. + * Handle for a DELETE /private/units/$UNIT operation. */ -struct TALER_MERCHANT_UnitDeleteHandle +struct TALER_MERCHANT_DeletePrivateUnitHandle { /** - * Fully qualified request URL. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * In-flight CURL job. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** - * Completion callback. + * Function to call with the result. */ - TALER_MERCHANT_UnitDeleteCallback cb; + TALER_MERCHANT_DeletePrivateUnitCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls; /** - * Execution context. + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Identifier of the unit to delete. + */ + char *unit_id; }; /** - * Called when the HTTP request finishes. + * Function called when we're done processing the + * HTTP DELETE /private/units/$UNIT request. * - * @param cls operation handle - * @param response_code HTTP status (0 on failure) - * @param response parsed JSON reply (NULL if unavailable) + * @param cls the `struct TALER_MERCHANT_DeletePrivateUnitHandle` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON */ static void handle_delete_unit_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_UnitDeleteHandle *udh = cls; + struct TALER_MERCHANT_DeletePrivateUnitHandle *duh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateUnitResponse dur = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - udh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "DELETE /private/units finished with status %u\n", + duh->job = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got /private/units/$UNIT DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; - case MHD_HTTP_BAD_REQUEST: case MHD_HTTP_UNAUTHORIZED: - case MHD_HTTP_FORBIDDEN: + dur.hr.ec = TALER_JSON_get_error_code (json); + dur.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_NOT_FOUND: - case MHD_HTTP_CONFLICT: - case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dur.hr.ec = TALER_JSON_get_error_code (json); + dur.hr.hint = TALER_JSON_get_error_hint (json); break; - case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + case MHD_HTTP_CONFLICT: + dur.hr.ec = TALER_JSON_get_error_code (json); + dur.hr.hint = TALER_JSON_get_error_hint (json); break; default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &hr); + dur.hr.ec = TALER_JSON_get_error_code (json); + dur.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response %u/%d for DELETE /private/units\n", + "Unexpected response code %u/%d for DELETE /private/units/$UNIT\n", (unsigned int) response_code, - (int) hr.ec); - GNUNET_break_op (0); + (int) dur.hr.ec); break; } - udh->cb (udh->cb_cls, - &hr); - TALER_MERCHANT_unit_delete_cancel (udh); + duh->cb (duh->cb_cls, + &dur); + TALER_MERCHANT_delete_private_unit_cancel (duh); } -struct TALER_MERCHANT_UnitDeleteHandle * -TALER_MERCHANT_unit_delete (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *unit_id, - TALER_MERCHANT_UnitDeleteCallback cb, - void *cb_cls) +struct TALER_MERCHANT_DeletePrivateUnitHandle * +TALER_MERCHANT_delete_private_unit_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *unit_id) +{ + struct TALER_MERCHANT_DeletePrivateUnitHandle *duh; + + duh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateUnitHandle); + duh->ctx = ctx; + duh->base_url = GNUNET_strdup (url); + duh->unit_id = GNUNET_strdup (unit_id); + return duh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_unit_start ( + struct TALER_MERCHANT_DeletePrivateUnitHandle *duh, + TALER_MERCHANT_DeletePrivateUnitCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_UnitDeleteHandle *udh; CURL *eh; - char *path; - - GNUNET_asprintf (&path, - "private/units/%s", - unit_id); - udh = GNUNET_new (struct TALER_MERCHANT_UnitDeleteHandle); - udh->ctx = ctx; - udh->cb = cb; - udh->cb_cls = cb_cls; - udh->url = TALER_url_join (backend_url, - path, - NULL); - GNUNET_free (path); - if (NULL == udh->url) + + duh->cb = cb; + duh->cb_cls = cb_cls; { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to build /private/units/%s URL\n", - unit_id); - GNUNET_free (udh); - return NULL; + char *path; + + GNUNET_asprintf (&path, + "private/units/%s", + duh->unit_id); + duh->url = TALER_url_join (duh->base_url, + path, + NULL); + GNUNET_free (path); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting DELETE on '%s'\n", - udh->url); - eh = TALER_MERCHANT_curl_easy_get_ (udh->url); + if (NULL == duh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (duh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_CUSTOMREQUEST, MHD_HTTP_METHOD_DELETE)); - udh->job = GNUNET_CURL_job_add (ctx, + duh->job = GNUNET_CURL_job_add (duh->ctx, eh, &handle_delete_unit_finished, - udh); - return udh; + duh); + if (NULL == duh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_unit_delete_cancel (struct TALER_MERCHANT_UnitDeleteHandle *udh) +TALER_MERCHANT_delete_private_unit_cancel ( + struct TALER_MERCHANT_DeletePrivateUnitHandle *duh) { - if (NULL != udh->job) - GNUNET_CURL_job_cancel (udh->job); - GNUNET_free (udh->url); - GNUNET_free (udh); + if (NULL != duh->job) + { + GNUNET_CURL_job_cancel (duh->job); + duh->job = NULL; + } + GNUNET_free (duh->url); + GNUNET_free (duh->unit_id); + GNUNET_free (duh->base_url); + GNUNET_free (duh); } -/* end of merchant_api_delete_unit.c */ +/* end of merchant_api_delete-private-units-UNIT-new.c */ diff --git a/src/lib/merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c b/src/lib/merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c @@ -1,203 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c - * @brief Implementation of the DELETE /private/webhooks/$WEBHOOK_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a DELETE /private/webhooks/$WEBHOOK_ID operation. - */ -struct TALER_MERCHANT_DeletePrivateWebhookHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_DeletePrivateWebhookCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Identifier of the webhook to delete. - */ - char *webhook_id; -}; - - -/** - * Function called when we're done processing the - * HTTP DELETE /private/webhooks/$WEBHOOK_ID request. - * - * @param cls the `struct TALER_MERCHANT_DeletePrivateWebhookHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_delete_webhook_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh = cls; - const json_t *json = response; - struct TALER_MERCHANT_DeletePrivateWebhookResponse dwr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - dwh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/webhooks/$WEBHOOK_ID DELETE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - dwr.hr.ec = TALER_JSON_get_error_code (json); - dwr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - case MHD_HTTP_NOT_FOUND: - dwr.hr.ec = TALER_JSON_get_error_code (json); - dwr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - dwr.hr.ec = TALER_JSON_get_error_code (json); - dwr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dwr.hr.ec = TALER_JSON_get_error_code (json); - dwr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d for DELETE /private/webhooks/$WEBHOOK_ID\n", - (unsigned int) response_code, - (int) dwr.hr.ec); - break; - } - dwh->cb (dwh->cb_cls, - &dwr); - TALER_MERCHANT_delete_private_webhook_cancel (dwh); -} - - -struct TALER_MERCHANT_DeletePrivateWebhookHandle * -TALER_MERCHANT_delete_private_webhook_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id) -{ - struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh; - - dwh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateWebhookHandle); - dwh->ctx = ctx; - dwh->base_url = GNUNET_strdup (url); - dwh->webhook_id = GNUNET_strdup (webhook_id); - return dwh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_delete_private_webhook_start ( - struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh, - TALER_MERCHANT_DeletePrivateWebhookCallback cb, - TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - dwh->cb = cb; - dwh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/webhooks/%s", - dwh->webhook_id); - dwh->url = TALER_url_join (dwh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == dwh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (dwh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - dwh->job = GNUNET_CURL_job_add (dwh->ctx, - eh, - &handle_delete_webhook_finished, - dwh); - if (NULL == dwh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_delete_private_webhook_cancel ( - struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh) -{ - if (NULL != dwh->job) - { - GNUNET_CURL_job_cancel (dwh->job); - dwh->job = NULL; - } - GNUNET_free (dwh->url); - GNUNET_free (dwh->base_url); - GNUNET_free (dwh->webhook_id); - GNUNET_free (dwh); -} - - -/* end of merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c */ diff --git a/src/lib/merchant_api_delete-private-webhooks-WEBHOOK_ID.c b/src/lib/merchant_api_delete-private-webhooks-WEBHOOK_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_delete-private-webhooks-WEBHOOK_ID.c - * @brief Implementation of the DELETE /webhooks/$ID request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c + * @brief Implementation of the DELETE /private/webhooks/$WEBHOOK_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a DELETE /webhooks/$ID operation. + * Handle for a DELETE /private/webhooks/$WEBHOOK_ID operation. */ -struct TALER_MERCHANT_WebhookDeleteHandle +struct TALER_MERCHANT_DeletePrivateWebhookHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_WebhookDeleteHandle /** * Function to call with the result. */ - TALER_MERCHANT_WebhookDeleteCallback cb; + TALER_MERCHANT_DeletePrivateWebhookCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Identifier of the webhook to delete. + */ + char *webhook_id; }; /** * Function called when we're done processing the - * HTTP GET /webhooks/$ID request. + * HTTP DELETE /private/webhooks/$WEBHOOK_ID request. * - * @param cls the `struct TALER_MERCHANT_WebhookDeleteHandle` + * @param cls the `struct TALER_MERCHANT_DeletePrivateWebhookHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,108 +85,119 @@ handle_delete_webhook_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WebhookDeleteHandle *wdh = cls; + struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_DeletePrivateWebhookResponse dwr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - wdh->job = NULL; + dwh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /webhooks/$ID response with status code %u\n", + "Got /private/webhooks/$WEBHOOK_ID DELETE response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dwr.hr.ec = TALER_JSON_get_error_code (json); + dwr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dwr.hr.ec = TALER_JSON_get_error_code (json); + dwr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dwr.hr.ec = TALER_JSON_get_error_code (json); + dwr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + dwr.hr.ec = TALER_JSON_get_error_code (json); + dwr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", + "Unexpected response code %u/%d for DELETE /private/webhooks/$WEBHOOK_ID\n", (unsigned int) response_code, - (int) hr.ec); + (int) dwr.hr.ec); break; } - wdh->cb (wdh->cb_cls, - &hr); - TALER_MERCHANT_webhook_delete_cancel (wdh); + dwh->cb (dwh->cb_cls, + &dwr); + TALER_MERCHANT_delete_private_webhook_cancel (dwh); } -struct TALER_MERCHANT_WebhookDeleteHandle * -TALER_MERCHANT_webhook_delete ( +struct TALER_MERCHANT_DeletePrivateWebhookHandle * +TALER_MERCHANT_delete_private_webhook_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *webhook_id, - TALER_MERCHANT_WebhookDeleteCallback cb, - void *cb_cls) + const char *url, + const char *webhook_id) +{ + struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh; + + dwh = GNUNET_new (struct TALER_MERCHANT_DeletePrivateWebhookHandle); + dwh->ctx = ctx; + dwh->base_url = GNUNET_strdup (url); + dwh->webhook_id = GNUNET_strdup (webhook_id); + return dwh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_delete_private_webhook_start ( + struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh, + TALER_MERCHANT_DeletePrivateWebhookCallback cb, + TALER_MERCHANT_DELETE_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_WebhookDeleteHandle *wdh; + CURL *eh; - wdh = GNUNET_new (struct TALER_MERCHANT_WebhookDeleteHandle); - wdh->ctx = ctx; - wdh->cb = cb; - wdh->cb_cls = cb_cls; + dwh->cb = cb; + dwh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/webhooks/%s", - webhook_id); - wdh->url = TALER_url_join (backend_url, + dwh->webhook_id); + dwh->url = TALER_url_join (dwh->base_url, path, NULL); GNUNET_free (path); } - if (NULL == wdh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (wdh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - wdh->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (wdh->url); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_DELETE)); - wdh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_delete_webhook_finished, - wdh); - } - return wdh; + if (NULL == dwh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (dwh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_DELETE)); + dwh->job = GNUNET_CURL_job_add (dwh->ctx, + eh, + &handle_delete_webhook_finished, + dwh); + if (NULL == dwh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_webhook_delete_cancel ( - struct TALER_MERCHANT_WebhookDeleteHandle *wdh) +TALER_MERCHANT_delete_private_webhook_cancel ( + struct TALER_MERCHANT_DeletePrivateWebhookHandle *dwh) { - if (NULL != wdh->job) - GNUNET_CURL_job_cancel (wdh->job); - GNUNET_free (wdh->url); - GNUNET_free (wdh); + if (NULL != dwh->job) + { + GNUNET_CURL_job_cancel (dwh->job); + dwh->job = NULL; + } + GNUNET_free (dwh->url); + GNUNET_free (dwh->base_url); + GNUNET_free (dwh->webhook_id); + GNUNET_free (dwh); } + + +/* end of merchant_api_delete-private-webhooks-WEBHOOK_ID-new.c */ diff --git a/src/lib/merchant_api_get-config-new.c b/src/lib/merchant_api_get-config-new.c @@ -1,335 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-config-new.c - * @brief Implementation of the GET /config request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-config-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> - -/** - * Which version of the Taler protocol is implemented - * by this library? Used to determine compatibility. - */ -#define MERCHANT_PROTOCOL_CURRENT 27 - -/** - * How many configs are we backwards-compatible with? - */ -#define MERCHANT_PROTOCOL_AGE 3 - -/** - * How many exchanges do we allow at most per merchant? - */ -#define MAX_EXCHANGES 1024 - -/** - * How many currency specs do we allow at most per merchant? - */ -#define MAX_CURRENCIES 1024 - - -/** - * Handle for a GET /config operation. - */ -struct TALER_MERCHANT_GetConfigHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetConfigCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /config request. - * - * @param cls the `struct TALER_MERCHANT_GetConfigHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_config_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetConfigHandle *gch = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetConfigResponse cr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gch->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /config response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *jcs; - const json_t *exchanges = NULL; - struct TALER_MERCHANT_GetConfigExchangeInfo *eci = NULL; - unsigned int num_eci = 0; - unsigned int nspec; - struct TALER_JSON_ProtocolVersion pv; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_object_const ("currencies", - &jcs), - GNUNET_JSON_spec_array_const ("exchanges", - &exchanges), - GNUNET_JSON_spec_string ("currency", - &cr.details.ok.ci.currency), - TALER_JSON_spec_version ("version", - &pv), - GNUNET_JSON_spec_string ("version", - &cr.details.ok.ci.version), - GNUNET_JSON_spec_end () - }; - - cr.details.ok.compat - = TALER_MERCHANT_GET_CONFIG_VC_PROTOCOL_ERROR; - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - cr.hr.http_status = 0; - cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - cr.details.ok.compat = TALER_MERCHANT_GET_CONFIG_VC_MATCH; - if (MERCHANT_PROTOCOL_CURRENT < pv.current) - { - cr.details.ok.compat |= TALER_MERCHANT_GET_CONFIG_VC_NEWER; - if (MERCHANT_PROTOCOL_CURRENT < pv.current - pv.age) - cr.details.ok.compat - |= TALER_MERCHANT_GET_CONFIG_VC_INCOMPATIBLE; - } - if (MERCHANT_PROTOCOL_CURRENT > pv.current) - { - cr.details.ok.compat |= TALER_MERCHANT_GET_CONFIG_VC_OLDER; - if (MERCHANT_PROTOCOL_CURRENT - MERCHANT_PROTOCOL_AGE > pv.current) - cr.details.ok.compat - |= TALER_MERCHANT_GET_CONFIG_VC_INCOMPATIBLE; - } - - nspec = (unsigned int) json_object_size (jcs); - if ( (nspec > MAX_CURRENCIES) || - (json_object_size (jcs) != (size_t) nspec) ) - { - GNUNET_break_op (0); - cr.hr.http_status = 0; - cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (NULL != exchanges) - { - num_eci = (unsigned int) json_array_size (exchanges); - if ( (num_eci > MAX_EXCHANGES) || - (json_array_size (exchanges) != (size_t) num_eci) ) - { - GNUNET_break_op (0); - cr.hr.http_status = 0; - cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - eci = GNUNET_new_array (num_eci, - struct TALER_MERCHANT_GetConfigExchangeInfo); - for (unsigned int i = 0; i<num_eci; i++) - { - struct TALER_MERCHANT_GetConfigExchangeInfo *ei = &eci[i]; - const json_t *ej = json_array_get (exchanges, - i); - struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_string ("currency", - &ei->currency), - GNUNET_JSON_spec_string ("base_url", - &ei->base_url), - GNUNET_JSON_spec_fixed_auto ("master_pub", - &ei->master_pub), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (ej, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - cr.hr.http_status = 0; - cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - GNUNET_free (eci); - break; - } - } - } - { - struct TALER_CurrencySpecification *cspecs; - unsigned int off = 0; - json_t *obj; - const char *curr; - - cspecs = GNUNET_new_array (nspec, - struct TALER_CurrencySpecification); - cr.details.ok.num_cspecs = nspec; - cr.details.ok.cspecs = cspecs; - cr.details.ok.num_exchanges = (unsigned int) num_eci; - cr.details.ok.exchanges = eci; - json_object_foreach ((json_t *) jcs, curr, obj) - { - struct TALER_CurrencySpecification *cs = &cspecs[off++]; - struct GNUNET_JSON_Specification cspec[] = { - TALER_JSON_spec_currency_specification (curr, - curr, - cs), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (jcs, - cspec, - NULL, NULL)) - { - GNUNET_break_op (0); - cr.hr.http_status = 0; - cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - GNUNET_free (eci); - TALER_CONFIG_free_currencies (off - 1, - cspecs); - break; - } - } - gch->cb (gch->cb_cls, - &cr); - GNUNET_free (eci); - TALER_CONFIG_free_currencies (nspec, - cspecs); - } - TALER_MERCHANT_get_config_cancel (gch); - return; - } - default: - cr.hr.ec = TALER_JSON_get_error_code (json); - cr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) cr.hr.ec); - break; - } - gch->cb (gch->cb_cls, - &cr); - TALER_MERCHANT_get_config_cancel (gch); -} - - -struct TALER_MERCHANT_GetConfigHandle * -TALER_MERCHANT_get_config_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetConfigHandle *gch; - - gch = GNUNET_new (struct TALER_MERCHANT_GetConfigHandle); - gch->ctx = ctx; - gch->base_url = GNUNET_strdup (url); - return gch; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_config_start ( - struct TALER_MERCHANT_GetConfigHandle *gch, - TALER_MERCHANT_GetConfigCallback cb, - TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gch->cb = cb; - gch->cb_cls = cb_cls; - gch->url = TALER_url_join (gch->base_url, - "config", - NULL); - if (NULL == gch->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gch->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gch->job = GNUNET_CURL_job_add (gch->ctx, - eh, - &handle_get_config_finished, - gch); - if (NULL == gch->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_config_cancel ( - struct TALER_MERCHANT_GetConfigHandle *gch) -{ - if (NULL != gch->job) - { - GNUNET_CURL_job_cancel (gch->job); - gch->job = NULL; - } - GNUNET_free (gch->url); - GNUNET_free (gch->base_url); - GNUNET_free (gch); -} - - -/* end of merchant_api_get-config-new.c */ diff --git a/src/lib/merchant_api_get-config.c b/src/lib/merchant_api_get-config.c @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-config.c - * @brief Implementation of the /config request of the merchant's HTTP API + * @file merchant_api_get-config-new.c + * @brief Implementation of the GET /config request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,7 +25,7 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-config.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> #include <taler/taler_signatures.h> @@ -51,13 +51,19 @@ */ #define MAX_CURRENCIES 1024 + /** - * @brief A handle for /config operations + * Handle for a GET /config operation. */ -struct TALER_MERCHANT_ConfigGetHandle +struct TALER_MERCHANT_GetConfigHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -69,53 +75,51 @@ struct TALER_MERCHANT_ConfigGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_ConfigCallback cb; + TALER_MERCHANT_GetConfigCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Function called when we're done processing the - * HTTP /config request. + * HTTP GET /config request. * - * @param cls the `struct TALER_MERCHANT_ConfigGetHandle` + * @param cls the `struct TALER_MERCHANT_GetConfigHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_config_finished (void *cls, - long response_code, - const void *response) +handle_get_config_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_ConfigGetHandle *vgh = cls; + struct TALER_MERCHANT_GetConfigHandle *gch = cls; const json_t *json = response; - struct TALER_MERCHANT_ConfigResponse cr = { + struct TALER_MERCHANT_GetConfigResponse cr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; + gch->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got /config response with status code %u\n", (unsigned int) response_code); - - vgh->job = NULL; switch (response_code) { case MHD_HTTP_OK: { const json_t *jcs; const json_t *exchanges = NULL; - struct TALER_MERCHANT_ExchangeConfigInfo *eci = NULL; + struct TALER_MERCHANT_GetConfigExchangeInfo *eci = NULL; unsigned int num_eci = 0; unsigned int nspec; struct TALER_JSON_ProtocolVersion pv; @@ -133,7 +137,8 @@ handle_config_finished (void *cls, GNUNET_JSON_spec_end () }; - cr.details.ok.compat = TALER_MERCHANT_VC_PROTOCOL_ERROR; + cr.details.ok.compat + = TALER_MERCHANT_GET_CONFIG_VC_PROTOCOL_ERROR; if (GNUNET_OK != GNUNET_JSON_parse (json, spec, @@ -144,18 +149,20 @@ handle_config_finished (void *cls, cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - cr.details.ok.compat = TALER_MERCHANT_VC_MATCH; + cr.details.ok.compat = TALER_MERCHANT_GET_CONFIG_VC_MATCH; if (MERCHANT_PROTOCOL_CURRENT < pv.current) { - cr.details.ok.compat |= TALER_MERCHANT_VC_NEWER; + cr.details.ok.compat |= TALER_MERCHANT_GET_CONFIG_VC_NEWER; if (MERCHANT_PROTOCOL_CURRENT < pv.current - pv.age) - cr.details.ok.compat |= TALER_MERCHANT_VC_INCOMPATIBLE; + cr.details.ok.compat + |= TALER_MERCHANT_GET_CONFIG_VC_INCOMPATIBLE; } if (MERCHANT_PROTOCOL_CURRENT > pv.current) { - cr.details.ok.compat |= TALER_MERCHANT_VC_OLDER; + cr.details.ok.compat |= TALER_MERCHANT_GET_CONFIG_VC_OLDER; if (MERCHANT_PROTOCOL_CURRENT - MERCHANT_PROTOCOL_AGE > pv.current) - cr.details.ok.compat |= TALER_MERCHANT_VC_INCOMPATIBLE; + cr.details.ok.compat + |= TALER_MERCHANT_GET_CONFIG_VC_INCOMPATIBLE; } nspec = (unsigned int) json_object_size (jcs); @@ -169,9 +176,9 @@ handle_config_finished (void *cls, } if (NULL != exchanges) { - num_eci = (unsigned int) json_object_size (exchanges); + num_eci = (unsigned int) json_array_size (exchanges); if ( (num_eci > MAX_EXCHANGES) || - (json_object_size (exchanges) != (size_t) num_eci) ) + (json_array_size (exchanges) != (size_t) num_eci) ) { GNUNET_break_op (0); cr.hr.http_status = 0; @@ -179,10 +186,10 @@ handle_config_finished (void *cls, break; } eci = GNUNET_new_array (num_eci, - struct TALER_MERCHANT_ExchangeConfigInfo); + struct TALER_MERCHANT_GetConfigExchangeInfo); for (unsigned int i = 0; i<num_eci; i++) { - struct TALER_MERCHANT_ExchangeConfigInfo *ei = &eci[i]; + struct TALER_MERCHANT_GetConfigExchangeInfo *ei = &eci[i]; const json_t *ej = json_array_get (exchanges, i); struct GNUNET_JSON_Specification ispec[] = { @@ -244,17 +251,16 @@ handle_config_finished (void *cls, break; } } - vgh->cb (vgh->cb_cls, + gch->cb (gch->cb_cls, &cr); GNUNET_free (eci); TALER_CONFIG_free_currencies (nspec, cspecs); } - TALER_MERCHANT_config_get_cancel (vgh); + TALER_MERCHANT_get_config_cancel (gch); return; } default: - /* unexpected response code */ cr.hr.ec = TALER_JSON_get_error_code (json); cr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -263,58 +269,67 @@ handle_config_finished (void *cls, (int) cr.hr.ec); break; } - vgh->cb (vgh->cb_cls, + gch->cb (gch->cb_cls, &cr); - TALER_MERCHANT_config_get_cancel (vgh); + TALER_MERCHANT_get_config_cancel (gch); } -struct TALER_MERCHANT_ConfigGetHandle * -TALER_MERCHANT_config_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_ConfigCallback config_cb, - void *config_cb_cls) +struct TALER_MERCHANT_GetConfigHandle * +TALER_MERCHANT_get_config_create ( + struct GNUNET_CURL_Context *ctx, + const char *url) +{ + struct TALER_MERCHANT_GetConfigHandle *gch; + + gch = GNUNET_new (struct TALER_MERCHANT_GetConfigHandle); + gch->ctx = ctx; + gch->base_url = GNUNET_strdup (url); + return gch; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_config_start ( + struct TALER_MERCHANT_GetConfigHandle *gch, + TALER_MERCHANT_GetConfigCallback cb, + TALER_MERCHANT_GET_CONFIG_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ConfigGetHandle *vgh; CURL *eh; - vgh = GNUNET_new (struct TALER_MERCHANT_ConfigGetHandle); - vgh->ctx = ctx; - vgh->cb = config_cb; - vgh->cb_cls = config_cb_cls; - vgh->url = TALER_url_join (backend_url, + gch->cb = cb; + gch->cb_cls = cb_cls; + gch->url = TALER_url_join (gch->base_url, "config", NULL); - if (NULL == vgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (vgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - vgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (vgh->url); - vgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gch->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gch->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gch->job = GNUNET_CURL_job_add (gch->ctx, eh, - &handle_config_finished, - vgh); - return vgh; + &handle_get_config_finished, + gch); + if (NULL == gch->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_config_get_cancel (struct TALER_MERCHANT_ConfigGetHandle *vgh) +TALER_MERCHANT_get_config_cancel ( + struct TALER_MERCHANT_GetConfigHandle *gch) { - if (NULL != vgh->job) + if (NULL != gch->job) { - GNUNET_CURL_job_cancel (vgh->job); - vgh->job = NULL; + GNUNET_CURL_job_cancel (gch->job); + gch->job = NULL; } - GNUNET_free (vgh->url); - GNUNET_free (vgh); + GNUNET_free (gch->url); + GNUNET_free (gch->base_url); + GNUNET_free (gch); } -/* end of merchant_api_config_get.c */ +/* end of merchant_api_get-config-new.c */ diff --git a/src/lib/merchant_api_get-management-instances-INSTANCE-new.c b/src/lib/merchant_api_get-management-instances-INSTANCE-new.c @@ -1,256 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-management-instances-INSTANCE-new.c - * @brief Implementation of the GET /management/instances/$INSTANCE request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-management-instances-INSTANCE-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /management/instances/$INSTANCE operation. - */ -struct TALER_MERCHANT_GetManagementInstanceHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * Instance identifier to query. - */ - char *instance_id; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetManagementInstanceCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /management/instances/$INSTANCE request. - * - * @param cls the `struct TALER_MERCHANT_GetManagementInstanceHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_instance_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetManagementInstanceHandle *gmi = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetManagementInstanceResponse igr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gmi->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /management/instances/$INSTANCE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *address; - const json_t *jurisdiction; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ( - "name", - &igr.details.ok.details.name), - GNUNET_JSON_spec_fixed_auto ( - "merchant_pub", - &igr.details.ok.details.merchant_pub), - GNUNET_JSON_spec_object_const ( - "address", - &address), - GNUNET_JSON_spec_object_const ( - "jurisdiction", - &jurisdiction), - GNUNET_JSON_spec_bool ( - "use_stefan", - &igr.details.ok.details.use_stefan), - GNUNET_JSON_spec_relative_time ( - "default_wire_transfer_delay", - &igr.details.ok.details.default_wire_transfer_delay), - GNUNET_JSON_spec_relative_time ( - "default_pay_delay", - &igr.details.ok.details.default_pay_delay), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_relative_time ( - "default_refund_delay", - &igr.details.ok.details.default_refund_delay), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_time_rounder_interval ( - "default_wire_transfer_rounding_interval", - &igr.details.ok.details.default_wire_transfer_rounding_interval), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - igr.hr.http_status = 0; - igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - igr.details.ok.details.address = address; - igr.details.ok.details.jurisdiction = jurisdiction; - gmi->cb (gmi->cb_cls, - &igr); - TALER_MERCHANT_get_management_instance_cancel (gmi); - return; - } - case MHD_HTTP_UNAUTHORIZED: - igr.hr.ec = TALER_JSON_get_error_code (json); - igr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - igr.hr.ec = TALER_JSON_get_error_code (json); - igr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - igr.hr.ec = TALER_JSON_get_error_code (json); - igr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) igr.hr.ec); - break; - } - gmi->cb (gmi->cb_cls, - &igr); - TALER_MERCHANT_get_management_instance_cancel (gmi); -} - - -struct TALER_MERCHANT_GetManagementInstanceHandle * -TALER_MERCHANT_get_management_instance_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id) -{ - struct TALER_MERCHANT_GetManagementInstanceHandle *gmi; - - gmi = GNUNET_new (struct TALER_MERCHANT_GetManagementInstanceHandle); - gmi->ctx = ctx; - gmi->base_url = GNUNET_strdup (url); - if (NULL != instance_id) - gmi->instance_id = GNUNET_strdup (instance_id); - return gmi; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_management_instance_start ( - struct TALER_MERCHANT_GetManagementInstanceHandle *gmi, - TALER_MERCHANT_GetManagementInstanceCallback cb, - TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gmi->cb = cb; - gmi->cb_cls = cb_cls; - if (NULL != gmi->instance_id) - { - char *path; - - GNUNET_asprintf (&path, - "instances/%s/private", - gmi->instance_id); - gmi->url = TALER_url_join (gmi->base_url, - path, - NULL); - GNUNET_free (path); - } - else - { - gmi->url = TALER_url_join (gmi->base_url, - "private", - NULL); - } - if (NULL == gmi->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gmi->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gmi->job = GNUNET_CURL_job_add (gmi->ctx, - eh, - &handle_get_instance_finished, - gmi); - if (NULL == gmi->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_management_instance_cancel ( - struct TALER_MERCHANT_GetManagementInstanceHandle *gmi) -{ - if (NULL != gmi->job) - { - GNUNET_CURL_job_cancel (gmi->job); - gmi->job = NULL; - } - GNUNET_free (gmi->url); - GNUNET_free (gmi->instance_id); - GNUNET_free (gmi->base_url); - GNUNET_free (gmi); -} - - -/* end of merchant_api_get-management-instances-INSTANCE-new.c */ diff --git a/src/lib/merchant_api_get-management-instances-INSTANCE.c b/src/lib/merchant_api_get-management-instances-INSTANCE.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-management-instances-INSTANCE.c - * @brief Implementation of the GET /instance/$ID request of the merchant's HTTP API + * @file merchant_api_get-management-instances-INSTANCE-new.c + * @brief Implementation of the GET /management/instances/$INSTANCE request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,20 +25,28 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-management-instances-INSTANCE.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_kyclogic_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /instances/$ID operation. + * Handle for a GET /management/instances/$INSTANCE operation. */ -struct TALER_MERCHANT_InstanceGetHandle +struct TALER_MERCHANT_GetManagementInstanceHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * Instance identifier to query. + */ + char *instance_id; + + /** + * The full URL for this request. */ char *url; @@ -50,26 +58,25 @@ struct TALER_MERCHANT_InstanceGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstanceGetCallback cb; + TALER_MERCHANT_GetManagementInstanceCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Function called when we're done processing the - * HTTP GET /instances/$ID request. + * HTTP GET /management/instances/$INSTANCE request. * - * @param cls the `struct TALER_MERCHANT_InstanceGetHandle` + * @param cls the `struct TALER_MERCHANT_GetManagementInstanceHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -78,16 +85,16 @@ handle_get_instance_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_InstanceGetHandle *igh = cls; + struct TALER_MERCHANT_GetManagementInstanceHandle *gmi = cls; const json_t *json = response; - struct TALER_MERCHANT_InstanceGetResponse igr = { + struct TALER_MERCHANT_GetManagementInstanceResponse igr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - igh->job = NULL; + gmi->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /instances/$ID response with status code %u\n", + "Got /management/instances/$INSTANCE response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -142,23 +149,20 @@ handle_get_instance_finished (void *cls, } igr.details.ok.details.address = address; igr.details.ok.details.jurisdiction = jurisdiction; - igh->cb (igh->cb_cls, + gmi->cb (gmi->cb_cls, &igr); - TALER_MERCHANT_instance_get_cancel (igh); + TALER_MERCHANT_get_management_instance_cancel (gmi); return; } case MHD_HTTP_UNAUTHORIZED: igr.hr.ec = TALER_JSON_get_error_code (json); igr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: - /* instance does not exist */ igr.hr.ec = TALER_JSON_get_error_code (json); igr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ igr.hr.ec = TALER_JSON_get_error_code (json); igr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -167,69 +171,86 @@ handle_get_instance_finished (void *cls, (int) igr.hr.ec); break; } - igh->cb (igh->cb_cls, + gmi->cb (gmi->cb_cls, &igr); - TALER_MERCHANT_instance_get_cancel (igh); + TALER_MERCHANT_get_management_instance_cancel (gmi); } -struct TALER_MERCHANT_InstanceGetHandle * -TALER_MERCHANT_instance_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - TALER_MERCHANT_InstanceGetCallback cb, - void *cb_cls) +struct TALER_MERCHANT_GetManagementInstanceHandle * +TALER_MERCHANT_get_management_instance_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *instance_id) { - struct TALER_MERCHANT_InstanceGetHandle *igh; - CURL *eh; + struct TALER_MERCHANT_GetManagementInstanceHandle *gmi; - igh = GNUNET_new (struct TALER_MERCHANT_InstanceGetHandle); - igh->ctx = ctx; - igh->cb = cb; - igh->cb_cls = cb_cls; + gmi = GNUNET_new (struct TALER_MERCHANT_GetManagementInstanceHandle); + gmi->ctx = ctx; + gmi->base_url = GNUNET_strdup (url); if (NULL != instance_id) + gmi->instance_id = GNUNET_strdup (instance_id); + return gmi; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_management_instance_start ( + struct TALER_MERCHANT_GetManagementInstanceHandle *gmi, + TALER_MERCHANT_GetManagementInstanceCallback cb, + TALER_MERCHANT_GET_MANAGEMENT_INSTANCE_RESULT_CLOSURE *cb_cls) +{ + CURL *eh; + + gmi->cb = cb; + gmi->cb_cls = cb_cls; + if (NULL != gmi->instance_id) { char *path; GNUNET_asprintf (&path, "instances/%s/private", - instance_id); - igh->url = TALER_url_join (backend_url, + gmi->instance_id); + gmi->url = TALER_url_join (gmi->base_url, path, NULL); GNUNET_free (path); } else { - igh->url = TALER_url_join (backend_url, + gmi->url = TALER_url_join (gmi->base_url, "private", NULL); } - if (NULL == igh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (igh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - igh->url); - eh = TALER_MERCHANT_curl_easy_get_ (igh->url); - igh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gmi->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gmi->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gmi->job = GNUNET_CURL_job_add (gmi->ctx, eh, &handle_get_instance_finished, - igh); - return igh; + gmi); + if (NULL == gmi->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instance_get_cancel ( - struct TALER_MERCHANT_InstanceGetHandle *igh) +TALER_MERCHANT_get_management_instance_cancel ( + struct TALER_MERCHANT_GetManagementInstanceHandle *gmi) { - if (NULL != igh->job) - GNUNET_CURL_job_cancel (igh->job); - GNUNET_free (igh->url); - GNUNET_free (igh); + if (NULL != gmi->job) + { + GNUNET_CURL_job_cancel (gmi->job); + gmi->job = NULL; + } + GNUNET_free (gmi->url); + GNUNET_free (gmi->instance_id); + GNUNET_free (gmi->base_url); + GNUNET_free (gmi); } + + +/* end of merchant_api_get-management-instances-INSTANCE-new.c */ diff --git a/src/lib/merchant_api_get-management-instances-new.c b/src/lib/merchant_api_get-management-instances-new.c @@ -1,277 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-management-instances-new.c - * @brief Implementation of the GET /management/instances request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-management-instances-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - -/** - * Maximum number of instances permitted. - */ -#define MAX_INSTANCES 1024 - - -/** - * Handle for a GET /management/instances operation. - */ -struct TALER_MERCHANT_GetManagementInstancesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetManagementInstancesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse instance information from @a ia. - * - * @param ia JSON array (or NULL!) with instance data - * @param[in] igr partially filled response - * @param gimh operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_instances (const json_t *ia, - struct TALER_MERCHANT_GetManagementInstancesResponse *igr, - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh) -{ - unsigned int iis_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) iis_len) || - (iis_len > MAX_INSTANCES) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetManagementInstancesInstanceInfo iis[ - GNUNET_NZL (iis_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetManagementInstancesInstanceInfo *ii = - &iis[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("name", - &ii->name), - GNUNET_JSON_spec_string ("id", - &ii->id), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &ii->merchant_pub), - GNUNET_JSON_spec_array_const ("payment_targets", - &ii->payment_targets), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - for (size_t i = 0; i<json_array_size (ii->payment_targets); i++) - { - if (! json_is_string (json_array_get (ii->payment_targets, - i))) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - } - igr->details.ok.iis_length = iis_len; - igr->details.ok.iis = iis; - gimh->cb (gimh->cb_cls, - igr); - gimh->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /management/instances request. - * - * @param cls the `struct TALER_MERCHANT_GetManagementInstancesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_instances_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetManagementInstancesResponse igr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gimh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /management/instances response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *instances; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("instances", - &instances), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - igr.hr.http_status = 0; - igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_instances (instances, - &igr, - gimh)) - { - TALER_MERCHANT_get_management_instances_cancel (gimh); - return; - } - igr.hr.http_status = 0; - igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - igr.hr.ec = TALER_JSON_get_error_code (json); - igr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - igr.hr.ec = TALER_JSON_get_error_code (json); - igr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) igr.hr.ec); - break; - } - gimh->cb (gimh->cb_cls, - &igr); - TALER_MERCHANT_get_management_instances_cancel (gimh); -} - - -struct TALER_MERCHANT_GetManagementInstancesHandle * -TALER_MERCHANT_get_management_instances_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh; - - gimh = GNUNET_new (struct TALER_MERCHANT_GetManagementInstancesHandle); - gimh->ctx = ctx; - gimh->base_url = GNUNET_strdup (url); - return gimh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_management_instances_start ( - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh, - TALER_MERCHANT_GetManagementInstancesCallback cb, - TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gimh->cb = cb; - gimh->cb_cls = cb_cls; - gimh->url = TALER_url_join (gimh->base_url, - "management/instances", - NULL); - if (NULL == gimh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gimh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gimh->job = GNUNET_CURL_job_add (gimh->ctx, - eh, - &handle_get_instances_finished, - gimh); - if (NULL == gimh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_management_instances_cancel ( - struct TALER_MERCHANT_GetManagementInstancesHandle *gimh) -{ - if (NULL != gimh->job) - { - GNUNET_CURL_job_cancel (gimh->job); - gimh->job = NULL; - } - GNUNET_free (gimh->url); - GNUNET_free (gimh->base_url); - GNUNET_free (gimh); -} - - -/* end of merchant_api_get-management-instances-new.c */ diff --git a/src/lib/merchant_api_get-management-instances.c b/src/lib/merchant_api_get-management-instances.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-management-instances.c - * @brief Implementation of the GET /instances request of the merchant's HTTP API + * @file merchant_api_get-management-instances-new.c + * @brief Implementation of the GET /management/instances request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,24 +25,28 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-management-instances.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> - /** * Maximum number of instances permitted. */ #define MAX_INSTANCES 1024 + /** - * Handle for a GET /instances operation. + * Handle for a GET /management/instances operation. */ -struct TALER_MERCHANT_InstancesGetHandle +struct TALER_MERCHANT_GetManagementInstancesHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -54,55 +58,50 @@ struct TALER_MERCHANT_InstancesGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstancesGetCallback cb; + TALER_MERCHANT_GetManagementInstancesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Parse instance information from @a ia. * - * @param json overall reply body * @param ia JSON array (or NULL!) with instance data - * @param igh operation handle + * @param[in] igr partially filled response + * @param gimh operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue -parse_instances (const json_t *json, - const json_t *ia, - struct TALER_MERCHANT_InstancesGetHandle *igh) +parse_instances (const json_t *ia, + struct TALER_MERCHANT_GetManagementInstancesResponse *igr, + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh) { unsigned int iis_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) iis_len) || + if ( (json_array_size (ia) != (size_t) iis_len) || (iis_len > MAX_INSTANCES) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_InstanceInformation iis[GNUNET_NZL (iis_len)]; + struct TALER_MERCHANT_GetManagementInstancesInstanceInfo iis[ + GNUNET_NZL (iis_len)]; size_t index; json_t *value; - struct TALER_MERCHANT_InstancesGetResponse igr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details.ok.iis_length = iis_len, - .details.ok.iis = iis - }; json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_InstanceInformation *ii = &iis[index]; + struct TALER_MERCHANT_GetManagementInstancesInstanceInfo *ii = + &iis[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("name", &ii->name), @@ -132,10 +131,12 @@ parse_instances (const json_t *json, return GNUNET_SYSERR; } } - } /* for all instances */ - igh->cb (igh->cb_cls, - &igr); - igh->cb = NULL; /* just to be sure */ + } + igr->details.ok.iis_length = iis_len; + igr->details.ok.iis = iis; + gimh->cb (gimh->cb_cls, + igr); + gimh->cb = NULL; } return GNUNET_OK; } @@ -143,27 +144,27 @@ parse_instances (const json_t *json, /** * Function called when we're done processing the - * HTTP /instances request. + * HTTP GET /management/instances request. * - * @param cls the `struct TALER_MERCHANT_InstancesGetHandle` + * @param cls the `struct TALER_MERCHANT_GetManagementInstancesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_instances_finished (void *cls, - long response_code, - const void *response) +handle_get_instances_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_InstancesGetHandle *igh = cls; + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh = cls; const json_t *json = response; - struct TALER_MERCHANT_InstancesGetResponse igr = { + struct TALER_MERCHANT_GetManagementInstancesResponse igr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - igh->job = NULL; + gimh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /instances response with status code %u\n", + "Got /management/instances response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -186,11 +187,11 @@ handle_instances_finished (void *cls, break; } if (GNUNET_OK == - parse_instances (json, - instances, - igh)) + parse_instances (instances, + &igr, + gimh)) { - TALER_MERCHANT_instances_get_cancel (igh); + TALER_MERCHANT_get_management_instances_cancel (gimh); return; } igr.hr.http_status = 0; @@ -202,7 +203,6 @@ handle_instances_finished (void *cls, igr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ igr.hr.ec = TALER_JSON_get_error_code (json); igr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -211,53 +211,67 @@ handle_instances_finished (void *cls, (int) igr.hr.ec); break; } - igh->cb (igh->cb_cls, - &igr); - TALER_MERCHANT_instances_get_cancel (igh); + gimh->cb (gimh->cb_cls, + &igr); + TALER_MERCHANT_get_management_instances_cancel (gimh); +} + + +struct TALER_MERCHANT_GetManagementInstancesHandle * +TALER_MERCHANT_get_management_instances_create ( + struct GNUNET_CURL_Context *ctx, + const char *url) +{ + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh; + + gimh = GNUNET_new (struct TALER_MERCHANT_GetManagementInstancesHandle); + gimh->ctx = ctx; + gimh->base_url = GNUNET_strdup (url); + return gimh; } -struct TALER_MERCHANT_InstancesGetHandle * -TALER_MERCHANT_instances_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_InstancesGetCallback instances_cb, - void *instances_cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_get_management_instances_start ( + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh, + TALER_MERCHANT_GetManagementInstancesCallback cb, + TALER_MERCHANT_GET_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_InstancesGetHandle *igh; CURL *eh; - igh = GNUNET_new (struct TALER_MERCHANT_InstancesGetHandle); - igh->ctx = ctx; - igh->cb = instances_cb; - igh->cb_cls = instances_cb_cls; - igh->url = TALER_url_join (backend_url, - "management/instances", - NULL); - if (NULL == igh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (igh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - igh->url); - eh = TALER_MERCHANT_curl_easy_get_ (igh->url); - igh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_instances_finished, - igh); - return igh; + gimh->cb = cb; + gimh->cb_cls = cb_cls; + gimh->url = TALER_url_join (gimh->base_url, + "management/instances", + NULL); + if (NULL == gimh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gimh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gimh->job = GNUNET_CURL_job_add (gimh->ctx, + eh, + &handle_get_instances_finished, + gimh); + if (NULL == gimh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instances_get_cancel ( - struct TALER_MERCHANT_InstancesGetHandle *igh) +TALER_MERCHANT_get_management_instances_cancel ( + struct TALER_MERCHANT_GetManagementInstancesHandle *gimh) { - if (NULL != igh->job) - GNUNET_CURL_job_cancel (igh->job); - GNUNET_free (igh->url); - GNUNET_free (igh); + if (NULL != gimh->job) + { + GNUNET_CURL_job_cancel (gimh->job); + gimh->job = NULL; + } + GNUNET_free (gimh->url); + GNUNET_free (gimh->base_url); + GNUNET_free (gimh); } + + +/* end of merchant_api_get-management-instances-new.c */ diff --git a/src/lib/merchant_api_get-orders-ORDER_ID-new.c b/src/lib/merchant_api_get-orders-ORDER_ID-new.c @@ -1,335 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2018-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-orders-ORDER_ID-new.c - * @brief Implementation of the GET /orders/$ORDER_ID request (wallet-facing) - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-orders-ORDER_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /orders/$ORDER_ID operation (wallet-facing). - */ -struct TALER_MERCHANT_GetOrdersHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetOrdersCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Order ID. - */ - char *order_id; - - /** - * Hash of the contract terms (for authentication). - */ - struct TALER_PrivateContractHashP h_contract; - - /** - * Session ID for repurchase detection, or NULL. - */ - char *session_id; - - /** - * Long polling timeout. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Minimum refund amount to wait for, or NULL if unset. - */ - struct TALER_Amount min_refund; - - /** - * True if @e min_refund was set. - */ - bool have_min_refund; - - /** - * If true, wait until refund is confirmed obtained. - */ - bool await_refund_obtained; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /orders/$ORDER_ID request (wallet-facing). - * - * @param cls the `struct TALER_MERCHANT_GetOrdersHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_order_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetOrdersHandle *oph = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetOrdersResponse owgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - oph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /orders/$ORDER_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_bool ("refunded", - &owgr.details.ok.refunded), - GNUNET_JSON_spec_bool ("refund_pending", - &owgr.details.ok.refund_pending), - TALER_JSON_spec_amount_any ("refund_amount", - &owgr.details.ok.refund_amount), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - owgr.hr.http_status = 0; - owgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - oph->cb (oph->cb_cls, - &owgr); - TALER_MERCHANT_get_orders_cancel (oph); - return; - } - case MHD_HTTP_PAYMENT_REQUIRED: - { - owgr.details.payment_required.taler_pay_uri - = json_string_value (json_object_get (json, - "taler_pay_uri")); - owgr.details.payment_required.already_paid_order_id - = json_string_value (json_object_get (json, - "already_paid_order_id")); - if (NULL == owgr.details.payment_required.taler_pay_uri) - { - owgr.hr.http_status = 0; - owgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - oph->cb (oph->cb_cls, - &owgr); - TALER_MERCHANT_get_orders_cancel (oph); - return; - } - default: - owgr.hr.ec = TALER_JSON_get_error_code (json); - owgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) owgr.hr.ec); - break; - } - oph->cb (oph->cb_cls, - &owgr); - TALER_MERCHANT_get_orders_cancel (oph); -} - - -struct TALER_MERCHANT_GetOrdersHandle * -TALER_MERCHANT_get_orders_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract) -{ - struct TALER_MERCHANT_GetOrdersHandle *oph; - - oph = GNUNET_new (struct TALER_MERCHANT_GetOrdersHandle); - oph->ctx = ctx; - oph->base_url = GNUNET_strdup (url); - oph->order_id = GNUNET_strdup (order_id); - oph->h_contract = *h_contract; - return oph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_orders_set_options_ ( - struct TALER_MERCHANT_GetOrdersHandle *oph, - unsigned int num_options, - const struct TALER_MERCHANT_GetOrdersOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - const struct TALER_MERCHANT_GetOrdersOptionValue *opt = - &options[i]; - - switch (opt->option) - { - case TALER_MERCHANT_GET_ORDERS_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT: - oph->timeout = opt->details.timeout; - break; - case TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID: - GNUNET_free (oph->session_id); - if (NULL != opt->details.session_id) - oph->session_id = GNUNET_strdup (opt->details.session_id); - break; - case TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND: - oph->min_refund = opt->details.min_refund; - oph->have_min_refund = true; - break; - case TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED: - oph->await_refund_obtained = opt->details.await_refund_obtained; - break; - default: - GNUNET_break (0); - return GNUNET_NO; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_orders_start ( - struct TALER_MERCHANT_GetOrdersHandle *oph, - TALER_MERCHANT_GetOrdersCallback cb, - TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - unsigned int tms; - - oph->cb = cb; - oph->cb_cls = cb_cls; - tms = (unsigned int) (oph->timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us); - { - struct GNUNET_CRYPTO_HashAsciiEncoded h_contract_s; - char *path; - char timeout_ms[32]; - - GNUNET_CRYPTO_hash_to_enc (&oph->h_contract.hash, - &h_contract_s); - GNUNET_snprintf (timeout_ms, - sizeof (timeout_ms), - "%u", - tms); - GNUNET_asprintf (&path, - "orders/%s", - oph->order_id); - oph->url = TALER_url_join (oph->base_url, - path, - "h_contract", - h_contract_s.encoding, - "session_id", - oph->session_id, - "timeout_ms", - (0 != tms) - ? timeout_ms - : NULL, - "refund", - oph->have_min_refund - ? TALER_amount2s (&oph->min_refund) - : NULL, - "await_refund_obtained", - oph->await_refund_obtained - ? "yes" - : NULL, - NULL); - GNUNET_free (path); - } - if (NULL == oph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (oph->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - if (0 != tms) - { - GNUNET_break (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_TIMEOUT_MS, - (long) (tms + 100L))); - } - oph->job = GNUNET_CURL_job_add (oph->ctx, - eh, - &handle_get_order_finished, - oph); - if (NULL == oph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_orders_cancel ( - struct TALER_MERCHANT_GetOrdersHandle *oph) -{ - if (NULL != oph->job) - { - GNUNET_CURL_job_cancel (oph->job); - oph->job = NULL; - } - GNUNET_free (oph->url); - GNUNET_free (oph->order_id); - GNUNET_free (oph->session_id); - GNUNET_free (oph->base_url); - GNUNET_free (oph); -} - - -/* end of merchant_api_get-orders-ORDER_ID-new.c */ diff --git a/src/lib/merchant_api_get-orders-ORDER_ID.c b/src/lib/merchant_api_get-orders-ORDER_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2018, 2020, 2022 Taler Systems SA + Copyright (C) 2018-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,11 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-orders-ORDER_ID.c - * @brief Implementation of the GET /orders/$ID request + * @file merchant_api_get-orders-ORDER_ID-new.c + * @brief Implementation of the GET /orders/$ORDER_ID request (wallet-facing) * @author Christian Grothoff - * @author Marcello Stanisci - * @author Florian Dold */ #include "taler/platform.h" #include <curl/curl.h> @@ -27,21 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-orders-ORDER_ID.h> #include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * @brief A GET /orders/$ID handle + * Handle for a GET /orders/$ORDER_ID operation (wallet-facing). */ -struct TALER_MERCHANT_OrderWalletGetHandle +struct TALER_MERCHANT_GetOrdersHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,67 +53,83 @@ struct TALER_MERCHANT_OrderWalletGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_OrderWalletGetCallback cb; + TALER_MERCHANT_GetOrdersCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; -}; + /** + * Order ID. + */ + char *order_id; -/** - * Convenience function to call the callback in @a owgh with an error code of - * @a ec and the exchange body being set to @a reply. - * - * @param owgh handle providing callback - * @param ec error code to return to application - * @param reply JSON reply we got from the exchange, can be NULL - */ -static void -cb_failure (struct TALER_MERCHANT_OrderWalletGetHandle *owgh, - enum TALER_ErrorCode ec, - const json_t *reply) -{ - struct TALER_MERCHANT_OrderWalletGetResponse owgr = { - .hr.ec = ec, - .hr.reply = reply - }; + /** + * Hash of the contract terms (for authentication). + */ + struct TALER_PrivateContractHashP h_contract; - owgh->cb (owgh->cb_cls, - &owgr); -} + /** + * Session ID for repurchase detection, or NULL. + */ + char *session_id; + + /** + * Long polling timeout. + */ + struct GNUNET_TIME_Relative timeout; + + /** + * Minimum refund amount to wait for, or NULL if unset. + */ + struct TALER_Amount min_refund; + + /** + * True if @e min_refund was set. + */ + bool have_min_refund; + + /** + * If true, wait until refund is confirmed obtained. + */ + bool await_refund_obtained; +}; /** - * Function called when we're done processing the GET /check-payment request. + * Function called when we're done processing the + * HTTP GET /orders/$ORDER_ID request (wallet-facing). * - * @param cls the `struct TALER_MERCHANT_OrderWalletGetHandle` + * @param cls the `struct TALER_MERCHANT_GetOrdersHandle` * @param response_code HTTP response code, 0 on error - * @param response response body, should be NULL + * @param response response body, NULL if not in JSON */ static void -handle_wallet_get_order_finished (void *cls, - long response_code, - const void *response) +handle_get_order_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_OrderWalletGetHandle *owgh = cls; + struct TALER_MERCHANT_GetOrdersHandle *oph = cls; const json_t *json = response; + struct TALER_MERCHANT_GetOrdersResponse owgr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json + }; - owgh->job = NULL; + oph->job = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got /orders/$ORDER_ID response with status code %u\n", + (unsigned int) response_code); switch (response_code) { case MHD_HTTP_OK: { - struct TALER_MERCHANT_OrderWalletGetResponse owgr = { - .hr.reply = json, - .hr.http_status = MHD_HTTP_OK - }; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_bool ("refunded", &owgr.details.ok.refunded), @@ -129,26 +145,17 @@ handle_wallet_get_order_finished (void *cls, spec, NULL, NULL)) { - GNUNET_break_op (0); - cb_failure (owgh, - TALER_EC_GENERIC_REPLY_MALFORMED, - json); - TALER_MERCHANT_wallet_order_get_cancel (owgh); - return; + owgr.hr.http_status = 0; + owgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; } - owgh->cb (owgh->cb_cls, - &owgr); - GNUNET_JSON_parse_free (spec); - break; + oph->cb (oph->cb_cls, + &owgr); + TALER_MERCHANT_get_orders_cancel (oph); + return; } case MHD_HTTP_PAYMENT_REQUIRED: { - struct TALER_MERCHANT_OrderWalletGetResponse owgr = { - .hr.reply = json, - .hr.http_status = MHD_HTTP_PAYMENT_REQUIRED - }; - - /* Status is: unpaid */ owgr.details.payment_required.taler_pay_uri = json_string_value (json_object_get (json, "taler_pay_uri")); @@ -157,70 +164,106 @@ handle_wallet_get_order_finished (void *cls, "already_paid_order_id")); if (NULL == owgr.details.payment_required.taler_pay_uri) { - GNUNET_break_op (0); - cb_failure (owgh, - TALER_EC_GENERIC_REPLY_MALFORMED, - json); + owgr.hr.http_status = 0; + owgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - owgh->cb (owgh->cb_cls, - &owgr); - break; + oph->cb (oph->cb_cls, + &owgr); + TALER_MERCHANT_get_orders_cancel (oph); + return; } default: - { - struct TALER_MERCHANT_OrderWalletGetResponse owgr = { - .hr.reply = json, - .hr.http_status = response_code - }; + owgr.hr.ec = TALER_JSON_get_error_code (json); + owgr.hr.hint = TALER_JSON_get_error_hint (json); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d\n", + (unsigned int) response_code, + (int) owgr.hr.ec); + break; + } + oph->cb (oph->cb_cls, + &owgr); + TALER_MERCHANT_get_orders_cancel (oph); +} + + +struct TALER_MERCHANT_GetOrdersHandle * +TALER_MERCHANT_get_orders_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct TALER_PrivateContractHashP *h_contract) +{ + struct TALER_MERCHANT_GetOrdersHandle *oph; + + oph = GNUNET_new (struct TALER_MERCHANT_GetOrdersHandle); + oph->ctx = ctx; + oph->base_url = GNUNET_strdup (url); + oph->order_id = GNUNET_strdup (order_id); + oph->h_contract = *h_contract; + return oph; +} - TALER_MERCHANT_parse_error_details_ (response, - response_code, - &owgr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Checking order status failed with HTTP status code %u/%d\n", - (unsigned int) response_code, - (int) owgr.hr.ec); - GNUNET_break_op (0); - owgh->cb (owgh->cb_cls, - &owgr); + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_orders_set_options_ ( + struct TALER_MERCHANT_GetOrdersHandle *oph, + unsigned int num_options, + const struct TALER_MERCHANT_GetOrdersOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_MERCHANT_GetOrdersOptionValue *opt = + &options[i]; + + switch (opt->option) + { + case TALER_MERCHANT_GET_ORDERS_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_ORDERS_OPTION_TIMEOUT: + oph->timeout = opt->details.timeout; + break; + case TALER_MERCHANT_GET_ORDERS_OPTION_SESSION_ID: + GNUNET_free (oph->session_id); + if (NULL != opt->details.session_id) + oph->session_id = GNUNET_strdup (opt->details.session_id); break; + case TALER_MERCHANT_GET_ORDERS_OPTION_MIN_REFUND: + oph->min_refund = opt->details.min_refund; + oph->have_min_refund = true; + break; + case TALER_MERCHANT_GET_ORDERS_OPTION_AWAIT_REFUND_OBTAINED: + oph->await_refund_obtained = opt->details.await_refund_obtained; + break; + default: + GNUNET_break (0); + return GNUNET_NO; } } - TALER_MERCHANT_wallet_order_get_cancel (owgh); + return GNUNET_OK; } -struct TALER_MERCHANT_OrderWalletGetHandle * -TALER_MERCHANT_wallet_order_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract, - struct GNUNET_TIME_Relative timeout, - const char *session_id, - const struct TALER_Amount *min_refund, - bool await_refund_obtained, - TALER_MERCHANT_OrderWalletGetCallback cb, - void *cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_get_orders_start ( + struct TALER_MERCHANT_GetOrdersHandle *oph, + TALER_MERCHANT_GetOrdersCallback cb, + TALER_MERCHANT_GET_ORDERS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderWalletGetHandle *owgh; + CURL *eh; unsigned int tms; - GNUNET_assert (NULL != backend_url); - GNUNET_assert (NULL != order_id); - owgh = GNUNET_new (struct TALER_MERCHANT_OrderWalletGetHandle); - owgh->ctx = ctx; - owgh->cb = cb; - owgh->cb_cls = cb_cls; - tms = (unsigned int) (timeout.rel_value_us + oph->cb = cb; + oph->cb_cls = cb_cls; + tms = (unsigned int) (oph->timeout.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us); { - char timeout_ms[32]; struct GNUNET_CRYPTO_HashAsciiEncoded h_contract_s; char *path; + char timeout_ms[32]; - GNUNET_CRYPTO_hash_to_enc (&h_contract->hash, + GNUNET_CRYPTO_hash_to_enc (&oph->h_contract.hash, &h_contract_s); GNUNET_snprintf (timeout_ms, sizeof (timeout_ms), @@ -228,79 +271,65 @@ TALER_MERCHANT_wallet_order_get ( tms); GNUNET_asprintf (&path, "orders/%s", - order_id); - owgh->url = TALER_url_join (backend_url, - path, - "h_contract", - h_contract_s.encoding, - "session_id", - session_id, - "timeout_ms", - (0 != tms) - ? timeout_ms - : NULL, - "refund", - (NULL != min_refund) - ? TALER_amount2s (min_refund) - : NULL, - "await_refund_obtained", - await_refund_obtained - ? "yes" - : NULL, - NULL); + oph->order_id); + oph->url = TALER_url_join (oph->base_url, + path, + "h_contract", + h_contract_s.encoding, + "session_id", + oph->session_id, + "timeout_ms", + (0 != tms) + ? timeout_ms + : NULL, + "refund", + oph->have_min_refund + ? TALER_amount2s (&oph->min_refund) + : NULL, + "await_refund_obtained", + oph->await_refund_obtained + ? "yes" + : NULL, + NULL); GNUNET_free (path); } - if (NULL == owgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (owgh); - return NULL; - } - + if (NULL == oph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (oph->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + if (0 != tms) { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (owgh->url); - if (0 != tms) - { - GNUNET_break (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_TIMEOUT_MS, - (long) (tms + 100L))); - } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Checking order status at %s\n", - owgh->url); - if (NULL == (owgh->job = - GNUNET_CURL_job_add (ctx, - eh, - &handle_wallet_get_order_finished, - owgh))) - { - GNUNET_break (0); - GNUNET_free (owgh->url); - GNUNET_free (owgh); - return NULL; - } + GNUNET_break (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_TIMEOUT_MS, + (long) (tms + 100L))); } - return owgh; + oph->job = GNUNET_CURL_job_add (oph->ctx, + eh, + &handle_get_order_finished, + oph); + if (NULL == oph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_wallet_order_get_cancel ( - struct TALER_MERCHANT_OrderWalletGetHandle *owgh) +TALER_MERCHANT_get_orders_cancel ( + struct TALER_MERCHANT_GetOrdersHandle *oph) { - if (NULL != owgh->job) + if (NULL != oph->job) { - GNUNET_CURL_job_cancel (owgh->job); - owgh->job = NULL; + GNUNET_CURL_job_cancel (oph->job); + oph->job = NULL; } - GNUNET_free (owgh->url); - GNUNET_free (owgh); + GNUNET_free (oph->url); + GNUNET_free (oph->order_id); + GNUNET_free (oph->session_id); + GNUNET_free (oph->base_url); + GNUNET_free (oph); } -/* end of merchant_api_wallet_get_order.c */ +/* end of merchant_api_get-orders-ORDER_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-accounts-H_WIRE-new.c b/src/lib/merchant_api_get-private-accounts-H_WIRE-new.c @@ -1,238 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-accounts-H_WIRE-new.c - * @brief Implementation of the GET /private/accounts/$H_WIRE request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-accounts-H_WIRE-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/accounts/$H_WIRE operation. - */ -struct TALER_MERCHANT_GetPrivateAccountHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * Instance identifier. - */ - char *instance_id; - - /** - * Hash of the wire details identifying the account. - */ - struct TALER_MerchantWireHashP h_wire; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateAccountCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /private/accounts/$H_WIRE request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateAccountHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_account_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateAccountHandle *gpa = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateAccountResponse agr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpa->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/accounts/$H_WIRE response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("salt", - &agr.details.ok.ad.salt), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_web_url ("credit_facade_url", - &agr.details.ok.ad.credit_facade_url), - NULL), - TALER_JSON_spec_full_payto_uri ("payto_uri", - &agr.details.ok.ad.payto_uri), - GNUNET_JSON_spec_fixed_auto ("h_wire", - &agr.details.ok.ad.h_wire), - GNUNET_JSON_spec_bool ("active", - &agr.details.ok.ad.active), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - gpa->cb (gpa->cb_cls, - &agr); - TALER_MERCHANT_get_private_account_cancel (gpa); - return; - } - agr.hr.http_status = 0; - agr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - agr.hr.ec = TALER_JSON_get_error_code (json); - agr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - agr.hr.ec = TALER_JSON_get_error_code (json); - agr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - agr.hr.ec = TALER_JSON_get_error_code (json); - agr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) agr.hr.ec); - break; - } - gpa->cb (gpa->cb_cls, - &agr); - TALER_MERCHANT_get_private_account_cancel (gpa); -} - - -struct TALER_MERCHANT_GetPrivateAccountHandle * -TALER_MERCHANT_get_private_account_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - const struct TALER_MerchantWireHashP *h_wire) -{ - struct TALER_MERCHANT_GetPrivateAccountHandle *gpa; - - gpa = GNUNET_new (struct TALER_MERCHANT_GetPrivateAccountHandle); - gpa->ctx = ctx; - gpa->base_url = GNUNET_strdup (url); - gpa->instance_id = GNUNET_strdup (instance_id); - gpa->h_wire = *h_wire; - return gpa; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_account_start ( - struct TALER_MERCHANT_GetPrivateAccountHandle *gpa, - TALER_MERCHANT_GetPrivateAccountCallback cb, - TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpa->cb = cb; - gpa->cb_cls = cb_cls; - { - char w_str[sizeof (gpa->h_wire) * 2]; - char *path; - char *end; - - end = GNUNET_STRINGS_data_to_string (&gpa->h_wire, - sizeof (gpa->h_wire), - w_str, - sizeof (w_str)); - *end = '\0'; - GNUNET_asprintf (&path, - "private/accounts/%s", - w_str); - gpa->url = TALER_url_join (gpa->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gpa->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpa->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpa->job = GNUNET_CURL_job_add (gpa->ctx, - eh, - &handle_get_account_finished, - gpa); - if (NULL == gpa->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_account_cancel ( - struct TALER_MERCHANT_GetPrivateAccountHandle *gpa) -{ - if (NULL != gpa->job) - { - GNUNET_CURL_job_cancel (gpa->job); - gpa->job = NULL; - } - GNUNET_free (gpa->url); - GNUNET_free (gpa->instance_id); - GNUNET_free (gpa->base_url); - GNUNET_free (gpa); -} - - -/* end of merchant_api_get-private-accounts-H_WIRE-new.c */ diff --git a/src/lib/merchant_api_get-private-accounts-H_WIRE.c b/src/lib/merchant_api_get-private-accounts-H_WIRE.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-accounts-H_WIRE.c - * @brief Implementation of the GET /accounts/$ID request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_get-private-accounts-H_WIRE-new.c + * @brief Implementation of the GET /private/accounts/$H_WIRE request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +25,33 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-accounts-H_WIRE.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /accounts/$ID operation. + * Handle for a GET /private/accounts/$H_WIRE operation. */ -struct TALER_MERCHANT_AccountGetHandle +struct TALER_MERCHANT_GetPrivateAccountHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * Instance identifier. + */ + char *instance_id; + + /** + * Hash of the wire details identifying the account. + */ + struct TALER_MerchantWireHashP h_wire; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +63,25 @@ struct TALER_MERCHANT_AccountGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_AccountGetCallback cb; + TALER_MERCHANT_GetPrivateAccountCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Function called when we're done processing the - * HTTP GET /accounts/$ID request. + * HTTP GET /private/accounts/$H_WIRE request. * - * @param cls the `struct TALER_MERCHANT_AccountGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateAccountHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,16 +90,16 @@ handle_get_account_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_AccountGetHandle *tgh = cls; + struct TALER_MERCHANT_GetPrivateAccountHandle *gpa = cls; const json_t *json = response; - struct TALER_MERCHANT_AccountGetResponse tgr = { + struct TALER_MERCHANT_GetPrivateAccountResponse agr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + gpa->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /accounts/$ID response with status code %u\n", + "Got /private/accounts/$H_WIRE response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -94,17 +107,17 @@ handle_get_account_finished (void *cls, { struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("salt", - &tgr.details.ok.ad.salt), + &agr.details.ok.ad.salt), GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_web_url ("credit_facade_url", - &tgr.details.ok.ad.credit_facade_url), + &agr.details.ok.ad.credit_facade_url), NULL), TALER_JSON_spec_full_payto_uri ("payto_uri", - &tgr.details.ok.ad.payto_uri), + &agr.details.ok.ad.payto_uri), GNUNET_JSON_spec_fixed_auto ("h_wire", - &tgr.details.ok.ad.h_wire), + &agr.details.ok.ad.h_wire), GNUNET_JSON_spec_bool ("active", - &tgr.details.ok.ad.active), + &agr.details.ok.ad.active), GNUNET_JSON_spec_end () }; @@ -113,99 +126,113 @@ handle_get_account_finished (void *cls, spec, NULL, NULL)) { - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_account_get_cancel (tgh); + gpa->cb (gpa->cb_cls, + &agr); + TALER_MERCHANT_get_private_account_cancel (gpa); return; } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + agr.hr.http_status = 0; + agr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + agr.hr.ec = TALER_JSON_get_error_code (json); + agr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + agr.hr.ec = TALER_JSON_get_error_code (json); + agr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + agr.hr.ec = TALER_JSON_get_error_code (json); + agr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) tgr.hr.ec); + (int) agr.hr.ec); break; } - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_account_get_cancel (tgh); + gpa->cb (gpa->cb_cls, + &agr); + TALER_MERCHANT_get_private_account_cancel (gpa); } -struct TALER_MERCHANT_AccountGetHandle * -TALER_MERCHANT_account_get ( +struct TALER_MERCHANT_GetPrivateAccountHandle * +TALER_MERCHANT_get_private_account_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, - const struct TALER_MerchantWireHashP *h_wire, - TALER_MERCHANT_AccountGetCallback cb, - void *cb_cls) + const struct TALER_MerchantWireHashP *h_wire) +{ + struct TALER_MERCHANT_GetPrivateAccountHandle *gpa; + + gpa = GNUNET_new (struct TALER_MERCHANT_GetPrivateAccountHandle); + gpa->ctx = ctx; + gpa->base_url = GNUNET_strdup (url); + gpa->instance_id = GNUNET_strdup (instance_id); + gpa->h_wire = *h_wire; + return gpa; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_account_start ( + struct TALER_MERCHANT_GetPrivateAccountHandle *gpa, + TALER_MERCHANT_GetPrivateAccountCallback cb, + TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_AccountGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_AccountGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; + gpa->cb = cb; + gpa->cb_cls = cb_cls; { - char w_str[sizeof (*h_wire) * 2]; + char w_str[sizeof (gpa->h_wire) * 2]; char *path; char *end; - end = GNUNET_STRINGS_data_to_string (h_wire, - sizeof (*h_wire), + end = GNUNET_STRINGS_data_to_string (&gpa->h_wire, + sizeof (gpa->h_wire), w_str, sizeof (w_str)); *end = '\0'; GNUNET_asprintf (&path, "private/accounts/%s", w_str); - tgh->url = TALER_url_join (backend_url, + gpa->url = TALER_url_join (gpa->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gpa->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpa->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpa->job = GNUNET_CURL_job_add (gpa->ctx, eh, &handle_get_account_finished, - tgh); - return tgh; + gpa); + if (NULL == gpa->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_account_get_cancel ( - struct TALER_MERCHANT_AccountGetHandle *tgh) +TALER_MERCHANT_get_private_account_cancel ( + struct TALER_MERCHANT_GetPrivateAccountHandle *gpa) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != gpa->job) + { + GNUNET_CURL_job_cancel (gpa->job); + gpa->job = NULL; + } + GNUNET_free (gpa->url); + GNUNET_free (gpa->instance_id); + GNUNET_free (gpa->base_url); + GNUNET_free (gpa); } + + +/* end of merchant_api_get-private-accounts-H_WIRE-new.c */ diff --git a/src/lib/merchant_api_get-private-accounts-new.c b/src/lib/merchant_api_get-private-accounts-new.c @@ -1,264 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-accounts-new.c - * @brief Implementation of the GET /private/accounts request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-accounts-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - -/** - * Maximum number of accounts permitted. - */ -#define MAX_ACCOUNTS 1024 - - -/** - * Handle for a GET /private/accounts operation. - */ -struct TALER_MERCHANT_GetPrivateAccountsHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateAccountsCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse account information from @a ia. - * - * @param ia JSON array (or NULL!) with account data - * @param[in] tgr partially filled response - * @param gah operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_accounts (const json_t *ia, - struct TALER_MERCHANT_GetPrivateAccountsResponse *tgr, - struct TALER_MERCHANT_GetPrivateAccountsHandle *gah) -{ - unsigned int accounts_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) accounts_len) || - (accounts_len > MAX_ACCOUNTS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateAccountsAccountEntry accounts[ - GNUNET_NZL (accounts_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateAccountsAccountEntry *ae = - &accounts[index]; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_full_payto_uri ("payto_uri", - &ae->payto_uri), - GNUNET_JSON_spec_fixed_auto ("h_wire", - &ae->h_wire), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - tgr->details.ok.accounts_length = accounts_len; - tgr->details.ok.accounts = accounts; - gah->cb (gah->cb_cls, - tgr); - gah->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/accounts request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateAccountsHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_accounts_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateAccountsHandle *gah = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateAccountsResponse tgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/accounts response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *accounts; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("accounts", - &accounts), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_accounts (accounts, - &tgr, - gah)) - { - TALER_MERCHANT_get_private_accounts_cancel (gah); - return; - } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) tgr.hr.ec); - break; - } - gah->cb (gah->cb_cls, - &tgr); - TALER_MERCHANT_get_private_accounts_cancel (gah); -} - - -struct TALER_MERCHANT_GetPrivateAccountsHandle * -TALER_MERCHANT_get_private_accounts_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateAccountsHandle *gah; - - gah = GNUNET_new (struct TALER_MERCHANT_GetPrivateAccountsHandle); - gah->ctx = ctx; - gah->base_url = GNUNET_strdup (url); - return gah; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_accounts_start ( - struct TALER_MERCHANT_GetPrivateAccountsHandle *gah, - TALER_MERCHANT_GetPrivateAccountsCallback cb, - TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gah->cb = cb; - gah->cb_cls = cb_cls; - gah->url = TALER_url_join (gah->base_url, - "private/accounts", - NULL); - if (NULL == gah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gah->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gah->job = GNUNET_CURL_job_add (gah->ctx, - eh, - &handle_get_accounts_finished, - gah); - if (NULL == gah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_accounts_cancel ( - struct TALER_MERCHANT_GetPrivateAccountsHandle *gah) -{ - if (NULL != gah->job) - { - GNUNET_CURL_job_cancel (gah->job); - gah->job = NULL; - } - GNUNET_free (gah->url); - GNUNET_free (gah->base_url); - GNUNET_free (gah); -} - - -/* end of merchant_api_get-private-accounts-new.c */ diff --git a/src/lib/merchant_api_get-private-accounts.c b/src/lib/merchant_api_get-private-accounts.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-accounts.c - * @brief Implementation of the GET /accounts request of the merchant's HTTP API + * @file merchant_api_get-private-accounts-new.c + * @brief Implementation of the GET /private/accounts request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,23 +25,28 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-accounts.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** * Maximum number of accounts permitted. */ #define MAX_ACCOUNTS 1024 + /** - * Handle for a GET /accounts operation. + * Handle for a GET /private/accounts operation. */ -struct TALER_MERCHANT_AccountsGetHandle +struct TALER_MERCHANT_GetPrivateAccountsHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -53,18 +58,17 @@ struct TALER_MERCHANT_AccountsGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_AccountsGetCallback cb; + TALER_MERCHANT_GetPrivateAccountsCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; @@ -73,34 +77,36 @@ struct TALER_MERCHANT_AccountsGetHandle * * @param ia JSON array (or NULL!) with account data * @param[in] tgr partially filled response - * @param tgh operation handle + * @param gah operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_accounts (const json_t *ia, - struct TALER_MERCHANT_AccountsGetResponse *tgr, - struct TALER_MERCHANT_AccountsGetHandle *tgh) + struct TALER_MERCHANT_GetPrivateAccountsResponse *tgr, + struct TALER_MERCHANT_GetPrivateAccountsHandle *gah) { - unsigned int tmpl_len = (unsigned int) json_array_size (ia); + unsigned int accounts_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) tmpl_len) || - (tmpl_len > MAX_ACCOUNTS) ) + if ( (json_array_size (ia) != (size_t) accounts_len) || + (accounts_len > MAX_ACCOUNTS) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_AccountEntry tmpl[GNUNET_NZL (tmpl_len)]; + struct TALER_MERCHANT_GetPrivateAccountsAccountEntry accounts[ + GNUNET_NZL (accounts_len)]; size_t index; json_t *value; json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_AccountEntry *ie = &tmpl[index]; + struct TALER_MERCHANT_GetPrivateAccountsAccountEntry *ae = + &accounts[index]; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_full_payto_uri ("payto_uri", - &ie->payto_uri), + &ae->payto_uri), GNUNET_JSON_spec_fixed_auto ("h_wire", - &ie->h_wire), + &ae->h_wire), GNUNET_JSON_spec_end () }; @@ -113,11 +119,11 @@ parse_accounts (const json_t *ia, return GNUNET_SYSERR; } } - tgr->details.ok.accounts_length = tmpl_len; - tgr->details.ok.accounts = tmpl; - tgh->cb (tgh->cb_cls, + tgr->details.ok.accounts_length = accounts_len; + tgr->details.ok.accounts = accounts; + gah->cb (gah->cb_cls, tgr); - tgh->cb = NULL; /* just to be sure */ + gah->cb = NULL; } return GNUNET_OK; } @@ -125,9 +131,9 @@ parse_accounts (const json_t *ia, /** * Function called when we're done processing the - * HTTP /accounts request. + * HTTP GET /private/accounts request. * - * @param cls the `struct TALER_MERCHANT_AccountsGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateAccountsHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -136,16 +142,16 @@ handle_get_accounts_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_AccountsGetHandle *tgh = cls; + struct TALER_MERCHANT_GetPrivateAccountsHandle *gah = cls; const json_t *json = response; - struct TALER_MERCHANT_AccountsGetResponse tgr = { + struct TALER_MERCHANT_GetPrivateAccountsResponse tgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + gah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /accounts response with status code %u\n", + "Got /private/accounts response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -170,9 +176,9 @@ handle_get_accounts_finished (void *cls, if (GNUNET_OK == parse_accounts (accounts, &tgr, - tgh)) + gah)) { - TALER_MERCHANT_accounts_get_cancel (tgh); + TALER_MERCHANT_get_private_accounts_cancel (gah); return; } tgr.hr.http_status = 0; @@ -182,10 +188,8 @@ handle_get_accounts_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; default: - /* unexpected response code */ tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -194,54 +198,67 @@ handle_get_accounts_finished (void *cls, (int) tgr.hr.ec); break; } - tgh->cb (tgh->cb_cls, + gah->cb (gah->cb_cls, &tgr); - TALER_MERCHANT_accounts_get_cancel (tgh); + TALER_MERCHANT_get_private_accounts_cancel (gah); } -struct TALER_MERCHANT_AccountsGetHandle * -TALER_MERCHANT_accounts_get ( +struct TALER_MERCHANT_GetPrivateAccountsHandle * +TALER_MERCHANT_get_private_accounts_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_AccountsGetCallback cb, - void *cb_cls) + const char *url) +{ + struct TALER_MERCHANT_GetPrivateAccountsHandle *gah; + + gah = GNUNET_new (struct TALER_MERCHANT_GetPrivateAccountsHandle); + gah->ctx = ctx; + gah->base_url = GNUNET_strdup (url); + return gah; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_accounts_start ( + struct TALER_MERCHANT_GetPrivateAccountsHandle *gah, + TALER_MERCHANT_GetPrivateAccountsCallback cb, + TALER_MERCHANT_GET_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_AccountsGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_AccountsGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; - tgh->url = TALER_url_join (backend_url, + gah->cb = cb; + gah->cb_cls = cb_cls; + gah->url = TALER_url_join (gah->base_url, "private/accounts", NULL); - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gah->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gah->job = GNUNET_CURL_job_add (gah->ctx, eh, &handle_get_accounts_finished, - tgh); - return tgh; + gah); + if (NULL == gah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_accounts_get_cancel ( - struct TALER_MERCHANT_AccountsGetHandle *tgh) +TALER_MERCHANT_get_private_accounts_cancel ( + struct TALER_MERCHANT_GetPrivateAccountsHandle *gah) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != gah->job) + { + GNUNET_CURL_job_cancel (gah->job); + gah->job = NULL; + } + GNUNET_free (gah->url); + GNUNET_free (gah->base_url); + GNUNET_free (gah); } + + +/* end of merchant_api_get-private-accounts-new.c */ diff --git a/src/lib/merchant_api_get-private-donau-new.c b/src/lib/merchant_api_get-private-donau-new.c @@ -1,302 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2024-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-donau-new.c - * @brief Implementation of the GET /private/donau request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-donau-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of Donau instances permitted. - */ -#define MAX_DONAU_INSTANCES 1024 - - -/** - * Handle for a GET /private/donau operation. - */ -struct TALER_MERCHANT_GetPrivateDonauHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateDonauCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse Donau instance information from @a ia. - * - * @param ia JSON array (or NULL!) with Donau instance data - * @param[in] dgr partially filled response - * @param gpdh operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_donau_instances (const json_t *ia, - struct TALER_MERCHANT_GetPrivateDonauResponse *dgr, - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh) -{ - unsigned int instances_len = (unsigned int) json_array_size (ia); - struct DONAU_Keys *donau_keys_ptr = NULL; - - if ( (json_array_size (ia) != (size_t) instances_len) || - (instances_len > MAX_DONAU_INSTANCES) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry instances[ - GNUNET_NZL (instances_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry *instance = - &instances[index]; - const json_t *donau_keys_json = NULL; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_uint64 ("donau_instance_serial", - &instance->donau_instance_serial), - GNUNET_JSON_spec_string ("donau_url", - &instance->donau_url), - GNUNET_JSON_spec_string ("charity_name", - &instance->charity_name), - GNUNET_JSON_spec_fixed_auto ("charity_pub_key", - &instance->charity_pub_key), - GNUNET_JSON_spec_uint64 ("charity_id", - &instance->charity_id), - TALER_JSON_spec_amount_any ("charity_max_per_year", - &instance->charity_max_per_year), - TALER_JSON_spec_amount_any ("charity_receipts_to_date", - &instance->charity_receipts_to_date), - GNUNET_JSON_spec_int64 ("current_year", - &instance->current_year), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("donau_keys_json", - &donau_keys_json), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - /* Parse the Donau keys */ - if (NULL != donau_keys_json) - { - donau_keys_ptr = DONAU_keys_from_json (donau_keys_json); - if (NULL == donau_keys_ptr) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to convert donau keys from JSON\n"); - return GNUNET_SYSERR; - } - instance->donau_keys = donau_keys_ptr; - } - } - dgr->details.ok.donau_instances_length = instances_len; - dgr->details.ok.donau_instances = instances; - gpdh->cb (gpdh->cb_cls, - dgr); - gpdh->cb = NULL; - if (NULL != donau_keys_ptr) - { - DONAU_keys_decref (donau_keys_ptr); - donau_keys_ptr = NULL; - } - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/donau request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateDonauHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_donau_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateDonauResponse dgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpdh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/donau response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *donau_instances; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("donau_instances", - &donau_instances), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - dgr.hr.http_status = 0; - dgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_donau_instances (donau_instances, - &dgr, - gpdh)) - { - TALER_MERCHANT_get_private_donau_cancel (gpdh); - return; - } - dgr.hr.http_status = 0; - dgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - case MHD_HTTP_NOT_FOUND: - dgr.hr.ec = TALER_JSON_get_error_code (json); - dgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - dgr.hr.ec = TALER_JSON_get_error_code (json); - dgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) dgr.hr.ec); - break; - } - gpdh->cb (gpdh->cb_cls, - &dgr); - TALER_MERCHANT_get_private_donau_cancel (gpdh); -} - - -struct TALER_MERCHANT_GetPrivateDonauHandle * -TALER_MERCHANT_get_private_donau_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh; - - gpdh = GNUNET_new (struct TALER_MERCHANT_GetPrivateDonauHandle); - gpdh->ctx = ctx; - gpdh->base_url = GNUNET_strdup (url); - return gpdh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_donau_start ( - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh, - TALER_MERCHANT_GetPrivateDonauCallback cb, - TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpdh->cb = cb; - gpdh->cb_cls = cb_cls; - gpdh->url = TALER_url_join (gpdh->base_url, - "private/donau", - NULL); - if (NULL == gpdh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpdh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpdh->job = GNUNET_CURL_job_add (gpdh->ctx, - eh, - &handle_get_donau_finished, - gpdh); - if (NULL == gpdh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_donau_cancel ( - struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh) -{ - if (NULL != gpdh->job) - { - GNUNET_CURL_job_cancel (gpdh->job); - gpdh->job = NULL; - } - GNUNET_free (gpdh->url); - GNUNET_free (gpdh->base_url); - GNUNET_free (gpdh); -} - - -/* end of merchant_api_get-private-donau-new.c */ diff --git a/src/lib/merchant_api_get-private-donau.c b/src/lib/merchant_api_get-private-donau.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2024 Taler Systems SA + Copyright (C) 2024-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -11,36 +11,43 @@ A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> - */ + TALER; see the file COPYING.LGPL. If not, see + <http://www.gnu.org/licenses/> +*/ /** - * @file merchant_api_get-private-donau.c - * @brief Implementation of the GET /donau request of the merchant's HTTP API - * @author Bohdan Potuzhnyi - * @author Vlada Svirsh + * @file merchant_api_get-private-donau-new.c + * @brief Implementation of the GET /private/donau request + * @author Christian Grothoff */ - #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> /* for HTTP status codes */ +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-donau.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> -/* DONAU RELATED IMPORTS */ -#include "taler/taler_merchant_donau.h" -#include <donau/donau_service.h> + + +/** + * Maximum number of Donau instances permitted. + */ +#define MAX_DONAU_INSTANCES 1024 + /** - * Handle for a GET /donau operation. + * Handle for a GET /private/donau operation. */ -struct TALER_MERCHANT_DonauInstanceGetHandle +struct TALER_MERCHANT_GetPrivateDonauHandle { /** - * The URL for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -52,12 +59,12 @@ struct TALER_MERCHANT_DonauInstanceGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_DonauInstanceGetCallback cb; + TALER_MERCHANT_GetPrivateDonauCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -65,95 +72,95 @@ struct TALER_MERCHANT_DonauInstanceGetHandle struct GNUNET_CURL_Context *ctx; }; + /** * Parse Donau instance information from @a ia. * * @param ia JSON array (or NULL!) with Donau instance data - * @param igr response to fill - * @param dgh operation handle + * @param[in] dgr partially filled response + * @param gpdh operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_donau_instances (const json_t *ia, - struct TALER_MERCHANT_DonauInstanceGetResponse *igr, - struct TALER_MERCHANT_DonauInstanceGetHandle *dgh) + struct TALER_MERCHANT_GetPrivateDonauResponse *dgr, + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh) { unsigned int instances_len = (unsigned int) json_array_size (ia); - struct TALER_MERCHANT_DonauInstanceEntry - instances[GNUNET_NZL (instances_len)]; - size_t index; - json_t *value; struct DONAU_Keys *donau_keys_ptr = NULL; - if ((json_array_size (ia) != (size_t) instances_len)) + if ( (json_array_size (ia) != (size_t) instances_len) || + (instances_len > MAX_DONAU_INSTANCES) ) { GNUNET_break (0); return GNUNET_SYSERR; } - - json_array_foreach (ia, - index, - value) { - struct TALER_MERCHANT_DonauInstanceEntry *instance = &instances[index]; - const json_t *donau_keys_json = NULL; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_uint64 ("donau_instance_serial", - &instance->donau_instance_serial), - GNUNET_JSON_spec_string ("donau_url", - &instance->donau_url), - GNUNET_JSON_spec_string ("charity_name", - &instance->charity_name), - GNUNET_JSON_spec_fixed_auto ("charity_pub_key", - &instance->charity_pub_key), - GNUNET_JSON_spec_uint64 ("charity_id", - &instance->charity_id), - TALER_JSON_spec_amount_any ("charity_max_per_year", - &instance->charity_max_per_year), - TALER_JSON_spec_amount_any ("charity_receipts_to_date", - &instance->charity_receipts_to_date), - GNUNET_JSON_spec_int64 ("current_year", - &instance->current_year), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("donau_keys_json", - &donau_keys_json), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, - NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } + struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry instances[ + GNUNET_NZL (instances_len)]; + size_t index; + json_t *value; - /* Parse the Donau keys */ - if (NULL != donau_keys_json) - { - donau_keys_ptr = DONAU_keys_from_json (donau_keys_json); - if (NULL == donau_keys_ptr) + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_GetPrivateDonauDonauInstanceEntry *instance = + &instances[index]; + const json_t *donau_keys_json = NULL; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_uint64 ("donau_instance_serial", + &instance->donau_instance_serial), + GNUNET_JSON_spec_string ("donau_url", + &instance->donau_url), + GNUNET_JSON_spec_string ("charity_name", + &instance->charity_name), + GNUNET_JSON_spec_fixed_auto ("charity_pub_key", + &instance->charity_pub_key), + GNUNET_JSON_spec_uint64 ("charity_id", + &instance->charity_id), + TALER_JSON_spec_amount_any ("charity_max_per_year", + &instance->charity_max_per_year), + TALER_JSON_spec_amount_any ("charity_receipts_to_date", + &instance->charity_receipts_to_date), + GNUNET_JSON_spec_int64 ("current_year", + &instance->current_year), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_object_const ("donau_keys_json", + &donau_keys_json), + NULL), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to convert donau keys from JSON\n"); + GNUNET_break_op (0); return GNUNET_SYSERR; } - instance->donau_keys = donau_keys_ptr; - } - } - igr->details.ok.donau_instances_length = instances_len; - igr->details.ok.donau_instances = instances; - dgh->cb (dgh->cb_cls, - igr); - dgh->cb = NULL; - if (NULL != donau_keys_ptr) - { - DONAU_keys_decref (donau_keys_ptr); - donau_keys_ptr= NULL; + /* Parse the Donau keys */ + if (NULL != donau_keys_json) + { + donau_keys_ptr = DONAU_keys_from_json (donau_keys_json); + if (NULL == donau_keys_ptr) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to convert donau keys from JSON\n"); + return GNUNET_SYSERR; + } + instance->donau_keys = donau_keys_ptr; + } + } + dgr->details.ok.donau_instances_length = instances_len; + dgr->details.ok.donau_instances = instances; + gpdh->cb (gpdh->cb_cls, + dgr); + gpdh->cb = NULL; + if (NULL != donau_keys_ptr) + { + DONAU_keys_decref (donau_keys_ptr); + donau_keys_ptr = NULL; + } } return GNUNET_OK; } @@ -161,29 +168,28 @@ parse_donau_instances (const json_t *ia, /** * Function called when we're done processing the - * HTTP /donau request. + * HTTP GET /private/donau request. * - * @param cls the `struct TALER_MERCHANT_DonauInstanceGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateDonauHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_get_donau_instances_finished (void *cls, - long response_code, - const void *response) +handle_get_donau_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_DonauInstanceGetHandle *dgh = cls; + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh = cls; const json_t *json = response; - struct TALER_MERCHANT_DonauInstanceGetResponse igr = { + struct TALER_MERCHANT_GetPrivateDonauResponse dgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - dgh->job = NULL; + gpdh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /donau response with status code %u\n", + "Got /private/donau response with status code %u\n", (unsigned int) response_code); - switch (response_code) { case MHD_HTTP_OK: @@ -198,102 +204,99 @@ handle_get_donau_instances_finished (void *cls, if (GNUNET_OK != GNUNET_JSON_parse (json, spec, - NULL, - NULL)) + NULL, NULL)) { - igr.hr.http_status = 0; - igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + dgr.hr.http_status = 0; + dgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - if (GNUNET_OK == parse_donau_instances (donau_instances, - &igr, - dgh)) + &dgr, + gpdh)) { - TALER_MERCHANT_donau_instances_get_cancel (dgh); + TALER_MERCHANT_get_private_donau_cancel (gpdh); return; } - - igr.hr.http_status = 0; - igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + dgr.hr.http_status = 0; + dgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - case MHD_HTTP_UNAUTHORIZED: case MHD_HTTP_NOT_FOUND: + dgr.hr.ec = TALER_JSON_get_error_code (json); + dgr.hr.hint = TALER_JSON_get_error_hint (json); + break; default: - igr.hr.ec = TALER_JSON_get_error_code (json); - igr.hr.hint = TALER_JSON_get_error_hint (json); + dgr.hr.ec = TALER_JSON_get_error_code (json); + dgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) igr.hr.ec); + (int) dgr.hr.ec); break; } + gpdh->cb (gpdh->cb_cls, + &dgr); + TALER_MERCHANT_get_private_donau_cancel (gpdh); +} + - dgh->cb (dgh->cb_cls, - &igr); - TALER_MERCHANT_donau_instances_get_cancel (dgh); +struct TALER_MERCHANT_GetPrivateDonauHandle * +TALER_MERCHANT_get_private_donau_create ( + struct GNUNET_CURL_Context *ctx, + const char *url) +{ + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh; + + gpdh = GNUNET_new (struct TALER_MERCHANT_GetPrivateDonauHandle); + gpdh->ctx = ctx; + gpdh->base_url = GNUNET_strdup (url); + return gpdh; } -/** - * Initiate the GET /donau request. - * - * @param ctx CURL context - * @param backend_url base URL for the backend - * @param cb callback function to handle the response - * @param cb_cls closure for the callback function - * @return the handle for the operation, or NULL on error - */ -struct TALER_MERCHANT_DonauInstanceGetHandle * -TALER_MERCHANT_donau_instances_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_DonauInstanceGetCallback cb, - void *cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_get_private_donau_start ( + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh, + TALER_MERCHANT_GetPrivateDonauCallback cb, + TALER_MERCHANT_GET_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_DonauInstanceGetHandle *dgh; CURL *eh; - dgh = GNUNET_new (struct TALER_MERCHANT_DonauInstanceGetHandle); - dgh->ctx = ctx; - dgh->cb = cb; - dgh->cb_cls = cb_cls; - dgh->url = TALER_url_join (backend_url, - "private/donau", - NULL); - if (NULL == dgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (dgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - dgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (dgh->url); - dgh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_donau_instances_finished, - dgh); - - return dgh; + gpdh->cb = cb; + gpdh->cb_cls = cb_cls; + gpdh->url = TALER_url_join (gpdh->base_url, + "private/donau", + NULL); + if (NULL == gpdh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpdh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpdh->job = GNUNET_CURL_job_add (gpdh->ctx, + eh, + &handle_get_donau_finished, + gpdh); + if (NULL == gpdh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } -/** - * Cancel the GET /donau instances operation. - * - * @param dgh request to cancel. - */ void -TALER_MERCHANT_donau_instances_get_cancel ( - struct TALER_MERCHANT_DonauInstanceGetHandle *dgh) +TALER_MERCHANT_get_private_donau_cancel ( + struct TALER_MERCHANT_GetPrivateDonauHandle *gpdh) { - if (NULL != dgh->job) - GNUNET_CURL_job_cancel (dgh->job); - GNUNET_free (dgh->url); - GNUNET_free (dgh); + if (NULL != gpdh->job) + { + GNUNET_CURL_job_cancel (gpdh->job); + gpdh->job = NULL; + } + GNUNET_free (gpdh->url); + GNUNET_free (gpdh->base_url); + GNUNET_free (gpdh); } + + +/* end of merchant_api_get-private-donau-new.c */ diff --git a/src/lib/merchant_api_get-private-kyc-new.c b/src/lib/merchant_api_get-private-kyc-new.c @@ -1,541 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2023-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-kyc-new.c - * @brief Implementation of the GET /private/kyc request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-kyc-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum length of the KYC arrays supported. - */ -#define MAX_KYC 1024 - - -/** - * Handle for a GET /private/kyc operation. - */ -struct TALER_MERCHANT_GetPrivateKycHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateKycCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Hash of the wire account to filter by, or NULL. - */ - const struct TALER_MerchantWireHashP *h_wire; - - /** - * Storage for the h_wire value (if set). - */ - struct TALER_MerchantWireHashP h_wire_val; - - /** - * True if @e h_wire was set. - */ - bool have_h_wire; - - /** - * Exchange URL filter, or NULL. - */ - char *exchange_url; - - /** - * Long-poll target. - */ - enum TALER_EXCHANGE_KycLongPollTarget lpt; - - /** - * Long polling timeout. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Instance ID for management mode, or NULL. - */ - char *instance_id; -}; - - -/** - * Parse @a jkyc response and call the continuation on success. - * - * @param kyc operation handle - * @param[in,out] kr response details - * @param jkyc array from the reply - * @return #GNUNET_OK on success (callback was called) - */ -static enum GNUNET_GenericReturnValue -parse_kyc (struct TALER_MERCHANT_GetPrivateKycHandle *kyc, - struct TALER_MERCHANT_GetPrivateKycResponse *kr, - const json_t *jkyc) -{ - unsigned int num_kycs = (unsigned int) json_array_size (jkyc); - unsigned int num_limits = 0; - unsigned int num_kycauths = 0; - unsigned int pos_limits = 0; - unsigned int pos_kycauths = 0; - - if ( (json_array_size (jkyc) != (size_t) num_kycs) || - (num_kycs > MAX_KYC) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - - for (unsigned int i = 0; i<num_kycs; i++) - { - const json_t *jlimits = NULL; - const json_t *jkycauths = NULL; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ( - "limits", - &jlimits), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ( - "payto_kycauths", - &jkycauths), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (jkyc, - i), - spec, - NULL, NULL)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - num_limits += json_array_size (jlimits); - num_kycauths += json_array_size (jkycauths); - } - - { - struct TALER_MERCHANT_GetPrivateKycRedirectDetail kycs[ - GNUNET_NZL (num_kycs)]; - struct TALER_EXCHANGE_AccountLimit limits[ - GNUNET_NZL (num_limits)]; - struct TALER_FullPayto payto_kycauths[ - GNUNET_NZL (num_kycauths)]; - - memset (kycs, - 0, - sizeof (kycs)); - for (unsigned int i = 0; i<num_kycs; i++) - { - struct TALER_MERCHANT_GetPrivateKycRedirectDetail *rd - = &kycs[i]; - const json_t *jlimits = NULL; - const json_t *jkycauths = NULL; - uint32_t hs; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_full_payto_uri ( - "payto_uri", - &rd->payto_uri), - TALER_JSON_spec_web_url ( - "exchange_url", - &rd->exchange_url), - GNUNET_JSON_spec_uint32 ( - "exchange_http_status", - &hs), - GNUNET_JSON_spec_bool ( - "no_keys", - &rd->no_keys), - GNUNET_JSON_spec_bool ( - "auth_conflict", - &rd->auth_conflict), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_ec ( - "exchange_code", - &rd->exchange_code), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_fixed_auto ( - "access_token", - &rd->access_token), - &rd->no_access_token), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ( - "limits", - &jlimits), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ( - "payto_kycauths", - &jkycauths), - NULL), - GNUNET_JSON_spec_end () - }; - size_t j; - json_t *jlimit; - json_t *jkycauth; - - if (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (jkyc, - i), - spec, - NULL, NULL)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - rd->exchange_http_status = (unsigned int) hs; - rd->limits = &limits[pos_limits]; - rd->limits_length = json_array_size (jlimits); - json_array_foreach (jlimits, j, jlimit) - { - struct TALER_EXCHANGE_AccountLimit *limit - = &limits[pos_limits]; - struct GNUNET_JSON_Specification jspec[] = { - TALER_JSON_spec_kycte ( - "operation_type", - &limit->operation_type), - GNUNET_JSON_spec_relative_time ( - "timeframe", - &limit->timeframe), - TALER_JSON_spec_amount_any ( - "threshold", - &limit->threshold), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ( - "soft_limit", - &limit->soft_limit), - NULL), - GNUNET_JSON_spec_end () - }; - - GNUNET_assert (pos_limits < num_limits); - limit->soft_limit = false; - if (GNUNET_OK != - GNUNET_JSON_parse (jlimit, - jspec, - NULL, NULL)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - pos_limits++; - } - rd->payto_kycauths = &payto_kycauths[pos_kycauths]; - rd->pkycauth_length = json_array_size (jkycauths); - json_array_foreach (jkycauths, j, jkycauth) - { - GNUNET_assert (pos_kycauths < num_kycauths); - payto_kycauths[pos_kycauths].full_payto - = (char *) json_string_value (jkycauth); - if (NULL == payto_kycauths[pos_kycauths].full_payto) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - pos_kycauths++; - } - } - kr->details.ok.kycs = kycs; - kr->details.ok.kycs_length = num_kycs; - kyc->cb (kyc->cb_cls, - kr); - kyc->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/kyc request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateKycHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_kyc_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateKycHandle *kyc = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateKycResponse kr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - kyc->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/kyc response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *jkyc; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("kyc_data", - &jkyc), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - kr.hr.http_status = 0; - kr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK != - parse_kyc (kyc, - &kr, - jkyc)) - { - kr.hr.http_status = 0; - kr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - /* parse_kyc called the continuation already */ - TALER_MERCHANT_get_private_kyc_cancel (kyc); - return; - } - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - kr.hr.ec = TALER_JSON_get_error_code (json); - kr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_SERVICE_UNAVAILABLE: - break; - default: - kr.hr.ec = TALER_JSON_get_error_code (json); - kr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) kr.hr.ec); - break; - } - kyc->cb (kyc->cb_cls, - &kr); - TALER_MERCHANT_get_private_kyc_cancel (kyc); -} - - -struct TALER_MERCHANT_GetPrivateKycHandle * -TALER_MERCHANT_get_private_kyc_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateKycHandle *kyc; - - kyc = GNUNET_new (struct TALER_MERCHANT_GetPrivateKycHandle); - kyc->ctx = ctx; - kyc->base_url = GNUNET_strdup (url); - kyc->lpt = TALER_EXCHANGE_KLPT_NONE; - return kyc; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_private_kyc_set_options_ ( - struct TALER_MERCHANT_GetPrivateKycHandle *kyc, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateKycOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - const struct TALER_MERCHANT_GetPrivateKycOptionValue *opt = - &options[i]; - - switch (opt->option) - { - case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE: - if (NULL != opt->details.h_wire) - { - kyc->h_wire_val = *opt->details.h_wire; - kyc->h_wire = &kyc->h_wire_val; - kyc->have_h_wire = true; - } - break; - case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL: - GNUNET_free (kyc->exchange_url); - if (NULL != opt->details.exchange_url) - kyc->exchange_url = GNUNET_strdup (opt->details.exchange_url); - break; - case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT: - kyc->lpt = opt->details.lpt; - break; - case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT: - kyc->timeout = opt->details.timeout; - break; - case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID: - GNUNET_free (kyc->instance_id); - if (NULL != opt->details.instance_id) - kyc->instance_id = GNUNET_strdup (opt->details.instance_id); - break; - default: - GNUNET_break (0); - return GNUNET_NO; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_kyc_start ( - struct TALER_MERCHANT_GetPrivateKycHandle *kyc, - TALER_MERCHANT_GetPrivateKycCallback cb, - TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - unsigned long long tms; - char timeout_ms[32]; - char lpt_str[32]; - char *base_path; - - kyc->cb = cb; - kyc->cb_cls = cb_cls; - - /* Build the base path depending on whether instance_id is set */ - if (NULL != kyc->instance_id) - { - GNUNET_asprintf (&base_path, - "%smanagement/instances/%s/", - kyc->base_url, - kyc->instance_id); - } - else - { - GNUNET_asprintf (&base_path, - "%sprivate/", - kyc->base_url); - } - - GNUNET_snprintf (lpt_str, - sizeof (lpt_str), - "%d", - (int) kyc->lpt); - tms = kyc->timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; - GNUNET_snprintf (timeout_ms, - 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); - GNUNET_free (base_path); - if (NULL == kyc->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (kyc->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - if (0 != tms) - { - GNUNET_break (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_TIMEOUT_MS, - (long) (tms + 100L))); - } - kyc->job = GNUNET_CURL_job_add (kyc->ctx, - eh, - &handle_get_kyc_finished, - kyc); - if (NULL == kyc->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_kyc_cancel ( - struct TALER_MERCHANT_GetPrivateKycHandle *kyc) -{ - if (NULL != kyc->job) - { - GNUNET_CURL_job_cancel (kyc->job); - kyc->job = NULL; - } - GNUNET_free (kyc->url); - GNUNET_free (kyc->exchange_url); - GNUNET_free (kyc->instance_id); - GNUNET_free (kyc->base_url); - GNUNET_free (kyc); -} - - -/* end of merchant_api_get-private-kyc-new.c */ diff --git a/src/lib/merchant_api_get-private-kyc.c b/src/lib/merchant_api_get-private-kyc.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023--2024 Taler Systems SA + Copyright (C) 2023-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-kyc.c - * @brief Implementation of the GET /kyc request of the merchant's HTTP API + * @file merchant_api_get-private-kyc-new.c + * @brief Implementation of the GET /private/kyc request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,10 +25,9 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-kyc.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** @@ -36,13 +35,19 @@ */ #define MAX_KYC 1024 + /** - * Handle for a GET /kyc operation. + * Handle for a GET /private/kyc operation. */ -struct TALER_MERCHANT_KycGetHandle +struct TALER_MERCHANT_GetPrivateKycHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -54,23 +59,57 @@ struct TALER_MERCHANT_KycGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_KycGetCallback cb; + TALER_MERCHANT_GetPrivateKycCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Hash of the wire account to filter by, or NULL. + */ + const struct TALER_MerchantWireHashP *h_wire; + + /** + * Storage for the h_wire value (if set). + */ + struct TALER_MerchantWireHashP h_wire_val; + + /** + * True if @e h_wire was set. + */ + bool have_h_wire; + + /** + * Exchange URL filter, or NULL. + */ + char *exchange_url; + + /** + * Long-poll target. + */ + enum TALER_EXCHANGE_KycLongPollTarget lpt; + + /** + * Long polling timeout. + */ + struct GNUNET_TIME_Relative timeout; + + /** + * Instance ID for management mode, or NULL. + */ + char *instance_id; }; /** - * Parse @a kyc response and call the continuation on success. + * Parse @a jkyc response and call the continuation on success. * * @param kyc operation handle * @param[in,out] kr response details @@ -78,8 +117,8 @@ struct TALER_MERCHANT_KycGetHandle * @return #GNUNET_OK on success (callback was called) */ static enum GNUNET_GenericReturnValue -parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, - struct TALER_MERCHANT_KycResponse *kr, +parse_kyc (struct TALER_MERCHANT_GetPrivateKycHandle *kyc, + struct TALER_MERCHANT_GetPrivateKycResponse *kr, const json_t *jkyc) { unsigned int num_kycs = (unsigned int) json_array_size (jkyc); @@ -120,19 +159,14 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, NULL, NULL)) { GNUNET_break (0); - json_dumpf (json_array_get (jkyc, - i), - stderr, - JSON_INDENT (2)); return GNUNET_SYSERR; } num_limits += json_array_size (jlimits); num_kycauths += json_array_size (jkycauths); } - { - struct TALER_MERCHANT_AccountKycRedirectDetail kycs[ + struct TALER_MERCHANT_GetPrivateKycRedirectDetail kycs[ GNUNET_NZL (num_kycs)]; struct TALER_EXCHANGE_AccountLimit limits[ GNUNET_NZL (num_limits)]; @@ -144,7 +178,7 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, sizeof (kycs)); for (unsigned int i = 0; i<num_kycs; i++) { - struct TALER_MERCHANT_AccountKycRedirectDetail *rd + struct TALER_MERCHANT_GetPrivateKycRedirectDetail *rd = &kycs[i]; const json_t *jlimits = NULL; const json_t *jkycauths = NULL; @@ -198,10 +232,6 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, NULL, NULL)) { GNUNET_break (0); - json_dumpf (json_array_get (jkyc, - i), - stderr, - JSON_INDENT (2)); return GNUNET_SYSERR; } rd->exchange_http_status = (unsigned int) hs; @@ -237,10 +267,6 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, NULL, NULL)) { GNUNET_break (0); - json_dumpf (json_array_get (jkyc, - i), - stderr, - JSON_INDENT (2)); return GNUNET_SYSERR; } pos_limits++; @@ -255,10 +281,6 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, if (NULL == payto_kycauths[pos_kycauths].full_payto) { GNUNET_break (0); - json_dumpf (json_array_get (jkyc, - i), - stderr, - JSON_INDENT (2)); return GNUNET_SYSERR; } pos_kycauths++; @@ -268,6 +290,7 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, kr->details.ok.kycs_length = num_kycs; kyc->cb (kyc->cb_cls, kr); + kyc->cb = NULL; } return GNUNET_OK; } @@ -275,9 +298,9 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, /** * Function called when we're done processing the - * HTTP /kyc request. + * HTTP GET /private/kyc request. * - * @param cls the `struct TALER_MERCHANT_KycGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateKycHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -286,16 +309,16 @@ handle_get_kyc_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_KycGetHandle *kyc = cls; + struct TALER_MERCHANT_GetPrivateKycHandle *kyc = cls; const json_t *json = response; - struct TALER_MERCHANT_KycResponse kr = { + struct TALER_MERCHANT_GetPrivateKycResponse kr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; kyc->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /kyc response with status code %u\n", + "Got /private/kyc response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -327,7 +350,7 @@ handle_get_kyc_finished (void *cls, break; } /* parse_kyc called the continuation already */ - TALER_MERCHANT_kyc_get_cancel (kyc); + TALER_MERCHANT_get_private_kyc_cancel (kyc); return; } case MHD_HTTP_NO_CONTENT: @@ -335,12 +358,10 @@ handle_get_kyc_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: kr.hr.ec = TALER_JSON_get_error_code (json); kr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_SERVICE_UNAVAILABLE: break; default: - /* unexpected response code */ kr.hr.ec = TALER_JSON_get_error_code (json); kr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -351,49 +372,108 @@ handle_get_kyc_finished (void *cls, } kyc->cb (kyc->cb_cls, &kr); - TALER_MERCHANT_kyc_get_cancel (kyc); + TALER_MERCHANT_get_private_kyc_cancel (kyc); } -/** - * Issue a GET KYC request to the backend. - * Returns KYC status of bank accounts. - * - * @param ctx execution context - * @param[in] url URL to use for the request, consumed! - * @param h_wire which bank account to query, NULL for all - * @param exchange_url which exchange to query, NULL for all - * @param lpt target for long polling - * @param timeout how long to wait for a reply - * @param cb function to call with the result - * @param cb_cls closure for @a cb - * @return handle for this operation, NULL upon errors - */ -static struct TALER_MERCHANT_KycGetHandle * -kyc_get (struct GNUNET_CURL_Context *ctx, - char *url, - const struct TALER_MerchantWireHashP *h_wire, - const char *exchange_url, - enum TALER_EXCHANGE_KycLongPollTarget lpt, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_KycGetCallback cb, - void *cb_cls) +struct TALER_MERCHANT_GetPrivateKycHandle * +TALER_MERCHANT_get_private_kyc_create ( + struct GNUNET_CURL_Context *ctx, + const char *url) +{ + struct TALER_MERCHANT_GetPrivateKycHandle *kyc; + + kyc = GNUNET_new (struct TALER_MERCHANT_GetPrivateKycHandle); + kyc->ctx = ctx; + kyc->base_url = GNUNET_strdup (url); + kyc->lpt = TALER_EXCHANGE_KLPT_NONE; + return kyc; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_kyc_set_options_ ( + struct TALER_MERCHANT_GetPrivateKycHandle *kyc, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateKycOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_MERCHANT_GetPrivateKycOptionValue *opt = + &options[i]; + + switch (opt->option) + { + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE: + if (NULL != opt->details.h_wire) + { + kyc->h_wire_val = *opt->details.h_wire; + kyc->h_wire = &kyc->h_wire_val; + kyc->have_h_wire = true; + } + break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL: + GNUNET_free (kyc->exchange_url); + if (NULL != opt->details.exchange_url) + kyc->exchange_url = GNUNET_strdup (opt->details.exchange_url); + break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT: + kyc->lpt = opt->details.lpt; + break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT: + kyc->timeout = opt->details.timeout; + break; + case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID: + GNUNET_free (kyc->instance_id); + if (NULL != opt->details.instance_id) + kyc->instance_id = GNUNET_strdup (opt->details.instance_id); + break; + default: + GNUNET_break (0); + return GNUNET_NO; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_kyc_start ( + struct TALER_MERCHANT_GetPrivateKycHandle *kyc, + TALER_MERCHANT_GetPrivateKycCallback cb, + TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_KycGetHandle *kyc; CURL *eh; + unsigned long long tms; char timeout_ms[32]; char lpt_str[32]; - unsigned long long tms; + char *base_path; - kyc = GNUNET_new (struct TALER_MERCHANT_KycGetHandle); - kyc->ctx = ctx; kyc->cb = cb; kyc->cb_cls = cb_cls; + + /* Build the base path depending on whether instance_id is set */ + if (NULL != kyc->instance_id) + { + GNUNET_asprintf (&base_path, + "%smanagement/instances/%s/", + kyc->base_url, + kyc->instance_id); + } + else + { + GNUNET_asprintf (&base_path, + "%sprivate/", + kyc->base_url); + } + GNUNET_snprintf (lpt_str, sizeof (lpt_str), "%d", - (int) lpt); - tms = timeout.rel_value_us + (int) kyc->lpt); + tms = kyc->timeout.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; GNUNET_snprintf (timeout_ms, sizeof (timeout_ms), @@ -401,37 +481,29 @@ kyc_get (struct GNUNET_CURL_Context *ctx, tms); kyc->url = TALER_url_join ( - url, + base_path, "kyc", "h_wire", - NULL == h_wire - ? NULL - : GNUNET_h2s_full (&h_wire->hash), + kyc->have_h_wire + ? GNUNET_h2s_full (&kyc->h_wire_val.hash) + : NULL, "exchange_url", - NULL == exchange_url - ? NULL - : exchange_url, + kyc->exchange_url, "timeout_ms", - GNUNET_TIME_relative_is_zero (timeout) + GNUNET_TIME_relative_is_zero (kyc->timeout) ? NULL : timeout_ms, "lpt", - TALER_EXCHANGE_KLPT_NONE == lpt + TALER_EXCHANGE_KLPT_NONE == kyc->lpt ? NULL : lpt_str, NULL); - GNUNET_free (url); + GNUNET_free (base_path); if (NULL == kyc->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (kyc); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - kyc->url); + return TALER_EC_GENERIC_CONFIGURATION_INVALID; eh = TALER_MERCHANT_curl_easy_get_ (kyc->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; if (0 != tms) { GNUNET_break (CURLE_OK == @@ -439,77 +511,31 @@ kyc_get (struct GNUNET_CURL_Context *ctx, CURLOPT_TIMEOUT_MS, (long) (tms + 100L))); } - kyc->job - = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_kyc_finished, - kyc); - return kyc; -} - - -struct TALER_MERCHANT_KycGetHandle * -TALER_MERCHANT_kyc_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MerchantWireHashP *h_wire, - const char *exchange_url, - enum TALER_EXCHANGE_KycLongPollTarget lpt, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_KycGetCallback cb, - void *cb_cls) -{ - char *url; - - GNUNET_asprintf (&url, - "%sprivate/", - backend_url); - return kyc_get (ctx, - url, /* consumed! */ - h_wire, - exchange_url, - lpt, - timeout, - cb, - cb_cls); -} - - -struct TALER_MERCHANT_KycGetHandle * -TALER_MERCHANT_management_kyc_get ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *instance_id, - const struct TALER_MerchantWireHashP *h_wire, - const char *exchange_url, - enum TALER_EXCHANGE_KycLongPollTarget lpt, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_KycGetCallback cb, - void *cb_cls) -{ - char *url; - - GNUNET_asprintf (&url, - "%smanagement/instances/%s/", - backend_url, - instance_id); - return kyc_get (ctx, - url, /* consumed! */ - h_wire, - exchange_url, - lpt, - timeout, - cb, - cb_cls); + kyc->job = GNUNET_CURL_job_add (kyc->ctx, + eh, + &handle_get_kyc_finished, + kyc); + if (NULL == kyc->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_kyc_get_cancel ( - struct TALER_MERCHANT_KycGetHandle *kyc) +TALER_MERCHANT_get_private_kyc_cancel ( + struct TALER_MERCHANT_GetPrivateKycHandle *kyc) { if (NULL != kyc->job) + { GNUNET_CURL_job_cancel (kyc->job); + kyc->job = NULL; + } GNUNET_free (kyc->url); + GNUNET_free (kyc->exchange_url); + GNUNET_free (kyc->instance_id); + GNUNET_free (kyc->base_url); GNUNET_free (kyc); } + + +/* end of merchant_api_get-private-kyc-new.c */ diff --git a/src/lib/merchant_api_get-private-orders-ORDER_ID-new.c b/src/lib/merchant_api_get-private-orders-ORDER_ID-new.c @@ -1,573 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2018-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-orders-ORDER_ID-new.c - * @brief Implementation of the GET /private/orders/$ORDER_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-orders-ORDER_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of refund details we return. - */ -#define MAX_REFUND_DETAILS 1024 - -/** - * Maximum number of wire details we return. - */ -#define MAX_WIRE_DETAILS 1024 - - -/** - * Handle for a GET /private/orders/$ORDER_ID operation. - */ -struct TALER_MERCHANT_GetPrivateOrderHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateOrderCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Order ID. - */ - char *order_id; - - /** - * Session ID for repurchase detection, or NULL. - */ - char *session_id; - - /** - * Long polling timeout. - */ - struct GNUNET_TIME_Relative timeout; -}; - - -/** - * Handle HTTP OK response for an unpaid order. - * - * @param oph handle for the request - * @param[in,out] osr HTTP response we got - */ -static void -handle_unpaid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - struct TALER_MERCHANT_GetPrivateOrderResponse *osr) -{ - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any ( - "total_amount", - &osr->details.ok.details.unpaid.contract_amount), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ( - "already_paid_order_id", - &osr->details.ok.details.unpaid.already_paid_order_id), - NULL), - GNUNET_JSON_spec_string ( - "taler_pay_uri", - &osr->details.ok.details.unpaid.taler_pay_uri), - GNUNET_JSON_spec_string ( - "summary", - &osr->details.ok.details.unpaid.summary), - GNUNET_JSON_spec_timestamp ( - "creation_time", - &osr->details.ok.details.unpaid.creation_time), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (osr->hr.reply, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - osr->details.ok.status = TALER_MERCHANT_OSC_UNPAID; - oph->cb (oph->cb_cls, - osr); -} - - -/** - * Handle HTTP OK response for a claimed order. - * - * @param oph handle for the request - * @param[in,out] osr HTTP response we got - */ -static void -handle_claimed (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - struct TALER_MERCHANT_GetPrivateOrderResponse *osr) -{ - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_object_const ( - "contract_terms", - &osr->details.ok.details.claimed.contract_terms), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (osr->hr.reply, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - osr->details.ok.status = TALER_MERCHANT_OSC_CLAIMED; - oph->cb (oph->cb_cls, - osr); -} - - -/** - * Handle HTTP OK response for a paid order. - * - * @param oph handle for the request - * @param[in,out] osr HTTP response we got - */ -static void -handle_paid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - struct TALER_MERCHANT_GetPrivateOrderResponse *osr) -{ - uint32_t hc32; - const json_t *wire_details; - const json_t *refund_details; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_bool ("refunded", - &osr->details.ok.details.paid.refunded), - GNUNET_JSON_spec_bool ("refund_pending", - &osr->details.ok.details.paid.refund_pending), - GNUNET_JSON_spec_bool ("wired", - &osr->details.ok.details.paid.wired), - TALER_JSON_spec_amount_any ("deposit_total", - &osr->details.ok.details.paid.deposit_total), - TALER_JSON_spec_ec ("exchange_code", - &osr->details.ok.details.paid.exchange_ec), - GNUNET_JSON_spec_uint32 ("exchange_http_status", - &hc32), - TALER_JSON_spec_amount_any ("refund_amount", - &osr->details.ok.details.paid.refund_amount), - GNUNET_JSON_spec_object_const ( - "contract_terms", - &osr->details.ok.details.paid.contract_terms), - GNUNET_JSON_spec_array_const ("wire_details", - &wire_details), - GNUNET_JSON_spec_array_const ("refund_details", - &refund_details), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ("last_payment", - &osr->details.ok.details.paid.last_payment), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (osr->hr.reply, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - osr->details.ok.status = TALER_MERCHANT_OSC_PAID; - osr->details.ok.details.paid.exchange_hc = (unsigned int) hc32; - { - unsigned int wts_len = (unsigned int) json_array_size (wire_details); - unsigned int ref_len = (unsigned int) json_array_size (refund_details); - - if ( (json_array_size (wire_details) != (size_t) wts_len) || - (wts_len > MAX_WIRE_DETAILS) ) - { - GNUNET_break (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - if ( (json_array_size (refund_details) != (size_t) ref_len) || - (ref_len > MAX_REFUND_DETAILS) ) - { - GNUNET_break (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - { - struct TALER_MERCHANT_WireTransfer wts[GNUNET_NZL (wts_len)]; - struct TALER_MERCHANT_GetPrivateOrderRefundDetail ref[ - GNUNET_NZL (ref_len)]; - - for (unsigned int i = 0; i<wts_len; i++) - { - struct TALER_MERCHANT_WireTransfer *wt = &wts[i]; - const json_t *w = json_array_get (wire_details, - i); - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_web_url ("exchange_url", - &wt->exchange_url), - GNUNET_JSON_spec_fixed_auto ("wtid", - &wt->wtid), - GNUNET_JSON_spec_timestamp ("execution_time", - &wt->execution_time), - TALER_JSON_spec_amount_any ("amount", - &wt->total_amount), - GNUNET_JSON_spec_bool ("confirmed", - &wt->confirmed), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (w, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - } - - for (unsigned int i = 0; i<ref_len; i++) - { - struct TALER_MERCHANT_GetPrivateOrderRefundDetail *ro = &ref[i]; - const json_t *w = json_array_get (refund_details, - i); - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_amount_any ("amount", - &ro->refund_amount), - GNUNET_JSON_spec_string ("reason", - &ro->reason), - GNUNET_JSON_spec_timestamp ("timestamp", - &ro->refund_time), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (w, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - osr); - return; - } - } - - osr->details.ok.details.paid.wts = wts; - osr->details.ok.details.paid.wts_len = wts_len; - osr->details.ok.details.paid.refunds = ref; - osr->details.ok.details.paid.refunds_len = ref_len; - oph->cb (oph->cb_cls, - osr); - } - } -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/orders/$ORDER_ID request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateOrderHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_private_order_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateOrderHandle *oph = cls; - const json_t *json = response; - const char *order_status; - struct TALER_MERCHANT_GetPrivateOrderResponse osr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - oph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/orders/$ORDER_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - /* see below */ - break; - case MHD_HTTP_ACCEPTED: - oph->cb (oph->cb_cls, - &osr); - TALER_MERCHANT_get_private_order_cancel (oph); - return; - case MHD_HTTP_UNAUTHORIZED: - osr.hr.ec = TALER_JSON_get_error_code (json); - osr.hr.hint = TALER_JSON_get_error_hint (json); - oph->cb (oph->cb_cls, - &osr); - TALER_MERCHANT_get_private_order_cancel (oph); - return; - case MHD_HTTP_NOT_FOUND: - osr.hr.ec = TALER_JSON_get_error_code (json); - osr.hr.hint = TALER_JSON_get_error_hint (json); - oph->cb (oph->cb_cls, - &osr); - TALER_MERCHANT_get_private_order_cancel (oph); - return; - case MHD_HTTP_GATEWAY_TIMEOUT: - osr.hr.ec = TALER_JSON_get_error_code (json); - osr.hr.hint = TALER_JSON_get_error_hint (json); - oph->cb (oph->cb_cls, - &osr); - TALER_MERCHANT_get_private_order_cancel (oph); - return; - default: - osr.hr.ec = TALER_JSON_get_error_code (json); - osr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Polling order status failed with HTTP status code %u/%d\n", - (unsigned int) response_code, - (int) osr.hr.ec); - GNUNET_break_op (0); - oph->cb (oph->cb_cls, - &osr); - TALER_MERCHANT_get_private_order_cancel (oph); - return; - } - - order_status = json_string_value (json_object_get (json, - "order_status")); - if (NULL == order_status) - { - GNUNET_break_op (0); - osr.hr.http_status = 0; - osr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - &osr); - TALER_MERCHANT_get_private_order_cancel (oph); - return; - } - - if (0 == strcmp ("paid", - order_status)) - { - handle_paid (oph, - &osr); - } - else if (0 == strcmp ("claimed", - order_status)) - { - handle_claimed (oph, - &osr); - } - else if (0 == strcmp ("unpaid", - order_status)) - { - handle_unpaid (oph, - &osr); - } - else - { - GNUNET_break_op (0); - osr.hr.http_status = 0; - osr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - oph->cb (oph->cb_cls, - &osr); - } - TALER_MERCHANT_get_private_order_cancel (oph); -} - - -struct TALER_MERCHANT_GetPrivateOrderHandle * -TALER_MERCHANT_get_private_order_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id) -{ - struct TALER_MERCHANT_GetPrivateOrderHandle *oph; - - oph = GNUNET_new (struct TALER_MERCHANT_GetPrivateOrderHandle); - oph->ctx = ctx; - oph->base_url = GNUNET_strdup (url); - oph->order_id = GNUNET_strdup (order_id); - return oph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_private_order_set_options_ ( - struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateOrderOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - const struct TALER_MERCHANT_GetPrivateOrderOptionValue *opt = - &options[i]; - - switch (opt->option) - { - case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID: - GNUNET_free (oph->session_id); - if (NULL != opt->details.session_id) - oph->session_id = GNUNET_strdup (opt->details.session_id); - break; - case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT: - oph->timeout = opt->details.timeout; - break; - default: - GNUNET_break (0); - return GNUNET_NO; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_order_start ( - struct TALER_MERCHANT_GetPrivateOrderHandle *oph, - TALER_MERCHANT_GetPrivateOrderCallback cb, - TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - unsigned int tms; - - oph->cb = cb; - oph->cb_cls = cb_cls; - tms = (unsigned int) (oph->timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us); - { - char *path; - char timeout_ms[32]; - - GNUNET_snprintf (timeout_ms, - sizeof (timeout_ms), - "%u", - tms); - GNUNET_asprintf (&path, - "private/orders/%s", - oph->order_id); - oph->url = TALER_url_join (oph->base_url, - path, - "session_id", - oph->session_id, - "timeout_ms", - (0 != tms) - ? timeout_ms - : NULL, - NULL); - GNUNET_free (path); - } - if (NULL == oph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (oph->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - if (0 != tms) - { - GNUNET_break (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_TIMEOUT_MS, - (long) (tms + 100L))); - } - oph->job = GNUNET_CURL_job_add (oph->ctx, - eh, - &handle_get_private_order_finished, - oph); - if (NULL == oph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_order_cancel ( - struct TALER_MERCHANT_GetPrivateOrderHandle *oph) -{ - if (NULL != oph->job) - { - GNUNET_CURL_job_cancel (oph->job); - oph->job = NULL; - } - GNUNET_free (oph->url); - GNUNET_free (oph->order_id); - GNUNET_free (oph->session_id); - GNUNET_free (oph->base_url); - GNUNET_free (oph); -} - - -/* end of merchant_api_get-private-orders-ORDER_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-orders-ORDER_ID.c b/src/lib/merchant_api_get-private-orders-ORDER_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2018, 2019, 2020 Taler Systems SA + Copyright (C) 2018-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,11 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-orders-ORDER_ID.c - * @brief Implementation of the GET /private/orders/$ORDER request + * @file merchant_api_get-private-orders-ORDER_ID-new.c + * @brief Implementation of the GET /private/orders/$ORDER_ID request * @author Christian Grothoff - * @author Marcello Stanisci - * @author Florian Dold */ #include "taler/platform.h" #include <curl/curl.h> @@ -27,10 +25,9 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-orders-ORDER_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** @@ -45,13 +42,17 @@ /** - * @brief A GET /private/orders/$ORDER handle + * Handle for a GET /private/orders/$ORDER_ID operation. */ -struct TALER_MERCHANT_OrderMerchantGetHandle +struct TALER_MERCHANT_GetPrivateOrderHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -63,31 +64,44 @@ struct TALER_MERCHANT_OrderMerchantGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_OrderMerchantGetCallback cb; + TALER_MERCHANT_GetPrivateOrderCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Order ID. + */ + char *order_id; + + /** + * Session ID for repurchase detection, or NULL. + */ + char *session_id; + + /** + * Long polling timeout. + */ + struct GNUNET_TIME_Relative timeout; }; /** - * Function called when we're done processing the GET /private/orders/$ORDER - * request and we got an HTTP status of OK and the order was unpaid. Parse - * the response and call the callback. + * Handle HTTP OK response for an unpaid order. * - * @param omgh handle for the request + * @param oph handle for the request * @param[in,out] osr HTTP response we got */ static void -handle_unpaid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, - struct TALER_MERCHANT_OrderStatusResponse *osr) +handle_unpaid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + struct TALER_MERCHANT_GetPrivateOrderResponse *osr) { struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount_any ( @@ -117,28 +131,26 @@ handle_unpaid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, { GNUNET_break_op (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } osr->details.ok.status = TALER_MERCHANT_OSC_UNPAID; - omgh->cb (omgh->cb_cls, - osr); + oph->cb (oph->cb_cls, + osr); } /** - * Function called when we're done processing the GET /private/orders/$ORDER - * request and we got an HTTP status of OK and the order was claimed but not - * paid. Parse the response and call the callback. + * Handle HTTP OK response for a claimed order. * - * @param omgh handle for the request + * @param oph handle for the request * @param[in,out] osr HTTP response we got */ static void -handle_claimed (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, - struct TALER_MERCHANT_OrderStatusResponse *osr) +handle_claimed (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + struct TALER_MERCHANT_GetPrivateOrderResponse *osr) { struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_object_const ( @@ -154,28 +166,26 @@ handle_claimed (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, { GNUNET_break_op (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } osr->details.ok.status = TALER_MERCHANT_OSC_CLAIMED; - omgh->cb (omgh->cb_cls, - osr); + oph->cb (oph->cb_cls, + osr); } /** - * Function called when we're done processing the GET /private/orders/$ORDER - * request and we got an HTTP status of OK and the order was paid. Parse - * the response and call the callback. + * Handle HTTP OK response for a paid order. * - * @param omgh handle for the request + * @param oph handle for the request * @param[in,out] osr HTTP response we got */ static void -handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, - struct TALER_MERCHANT_OrderStatusResponse *osr) +handle_paid (struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + struct TALER_MERCHANT_GetPrivateOrderResponse *osr) { uint32_t hc32; const json_t *wire_details; @@ -202,7 +212,6 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, &wire_details), GNUNET_JSON_spec_array_const ("refund_details", &refund_details), - /* Only available since **v14** */ GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("last_payment", &osr->details.ok.details.paid.last_payment), @@ -217,41 +226,41 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, { GNUNET_break_op (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } osr->details.ok.status = TALER_MERCHANT_OSC_PAID; - osr->details.ok.details.paid.exchange_hc = (unsigned int) hc32; { unsigned int wts_len = (unsigned int) json_array_size (wire_details); unsigned int ref_len = (unsigned int) json_array_size (refund_details); - if ( (json_array_size (wire_details) != (size_t) wts_len) || + if ( (json_array_size (wire_details) != (size_t) wts_len) || (wts_len > MAX_WIRE_DETAILS) ) { GNUNET_break (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } - if ( (json_array_size (refund_details) != (size_t) ref_len) || + if ( (json_array_size (refund_details) != (size_t) ref_len) || (ref_len > MAX_REFUND_DETAILS) ) { GNUNET_break (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } { struct TALER_MERCHANT_WireTransfer wts[GNUNET_NZL (wts_len)]; - struct TALER_MERCHANT_RefundOrderDetail ref[GNUNET_NZL (ref_len)]; + struct TALER_MERCHANT_GetPrivateOrderRefundDetail ref[ + GNUNET_NZL (ref_len)]; for (unsigned int i = 0; i<wts_len; i++) { @@ -279,16 +288,16 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, { GNUNET_break_op (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } } for (unsigned int i = 0; i<ref_len; i++) { - struct TALER_MERCHANT_RefundOrderDetail *ro = &ref[i]; + struct TALER_MERCHANT_GetPrivateOrderRefundDetail *ro = &ref[i]; const json_t *w = json_array_get (refund_details, i); struct GNUNET_JSON_Specification ispec[] = { @@ -308,9 +317,9 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, { GNUNET_break_op (0); osr->hr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); + osr->hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + osr); return; } } @@ -319,144 +328,187 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, osr->details.ok.details.paid.wts_len = wts_len; osr->details.ok.details.paid.refunds = ref; osr->details.ok.details.paid.refunds_len = ref_len; - omgh->cb (omgh->cb_cls, - osr); + oph->cb (oph->cb_cls, + osr); } } } /** - * Function called when we're done processing the GET /private/orders/$ORDER - * request. + * Function called when we're done processing the + * HTTP GET /private/orders/$ORDER_ID request. * - * @param cls the `struct TALER_MERCHANT_OrderMerchantGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateOrderHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_merchant_order_get_finished (void *cls, - long response_code, - const void *response) +handle_get_private_order_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_OrderMerchantGetHandle *omgh = cls; + struct TALER_MERCHANT_GetPrivateOrderHandle *oph = cls; const json_t *json = response; const char *order_status; - struct TALER_MERCHANT_OrderStatusResponse osr = { + struct TALER_MERCHANT_GetPrivateOrderResponse osr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - omgh->job = NULL; + oph->job = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got /private/orders/$ORDER_ID response with status code %u\n", + (unsigned int) response_code); switch (response_code) { case MHD_HTTP_OK: /* see below */ break; case MHD_HTTP_ACCEPTED: - /* see below */ - omgh->cb (omgh->cb_cls, - &osr); - TALER_MERCHANT_merchant_order_get_cancel (omgh); + oph->cb (oph->cb_cls, + &osr); + TALER_MERCHANT_get_private_order_cancel (oph); return; case MHD_HTTP_UNAUTHORIZED: osr.hr.ec = TALER_JSON_get_error_code (json); osr.hr.hint = TALER_JSON_get_error_hint (json); - omgh->cb (omgh->cb_cls, - &osr); - TALER_MERCHANT_merchant_order_get_cancel (omgh); + oph->cb (oph->cb_cls, + &osr); + TALER_MERCHANT_get_private_order_cancel (oph); return; case MHD_HTTP_NOT_FOUND: osr.hr.ec = TALER_JSON_get_error_code (json); osr.hr.hint = TALER_JSON_get_error_hint (json); - omgh->cb (omgh->cb_cls, - &osr); - TALER_MERCHANT_merchant_order_get_cancel (omgh); + oph->cb (oph->cb_cls, + &osr); + TALER_MERCHANT_get_private_order_cancel (oph); return; case MHD_HTTP_GATEWAY_TIMEOUT: osr.hr.ec = TALER_JSON_get_error_code (json); osr.hr.hint = TALER_JSON_get_error_hint (json); - omgh->cb (omgh->cb_cls, - &osr); - TALER_MERCHANT_merchant_order_get_cancel (omgh); + oph->cb (oph->cb_cls, + &osr); + TALER_MERCHANT_get_private_order_cancel (oph); return; default: osr.hr.ec = TALER_JSON_get_error_code (json); osr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Polling payment failed with HTTP status code %u/%d\n", + "Polling order status failed with HTTP status code %u/%d\n", (unsigned int) response_code, (int) osr.hr.ec); GNUNET_break_op (0); - omgh->cb (omgh->cb_cls, - &osr); - TALER_MERCHANT_merchant_order_get_cancel (omgh); + oph->cb (oph->cb_cls, + &osr); + TALER_MERCHANT_get_private_order_cancel (oph); return; } order_status = json_string_value (json_object_get (json, "order_status")); - if (NULL == order_status) { GNUNET_break_op (0); osr.hr.http_status = 0; - osr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - &osr); - TALER_MERCHANT_merchant_order_get_cancel (omgh); + osr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + &osr); + TALER_MERCHANT_get_private_order_cancel (oph); return; } if (0 == strcmp ("paid", order_status)) { - handle_paid (omgh, + handle_paid (oph, &osr); } else if (0 == strcmp ("claimed", order_status)) { - handle_claimed (omgh, + handle_claimed (oph, &osr); } else if (0 == strcmp ("unpaid", order_status)) { - handle_unpaid (omgh, + handle_unpaid (oph, &osr); } else { GNUNET_break_op (0); osr.hr.http_status = 0; - osr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - &osr); + osr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + oph->cb (oph->cb_cls, + &osr); } - TALER_MERCHANT_merchant_order_get_cancel (omgh); + TALER_MERCHANT_get_private_order_cancel (oph); } -struct TALER_MERCHANT_OrderMerchantGetHandle * -TALER_MERCHANT_merchant_order_get ( +struct TALER_MERCHANT_GetPrivateOrderHandle * +TALER_MERCHANT_get_private_order_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const char *session_id, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_OrderMerchantGetCallback cb, - void *cb_cls) + const char *url, + const char *order_id) +{ + struct TALER_MERCHANT_GetPrivateOrderHandle *oph; + + oph = GNUNET_new (struct TALER_MERCHANT_GetPrivateOrderHandle); + oph->ctx = ctx; + oph->base_url = GNUNET_strdup (url); + oph->order_id = GNUNET_strdup (order_id); + return oph; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_order_set_options_ ( + struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateOrderOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_MERCHANT_GetPrivateOrderOptionValue *opt = + &options[i]; + + switch (opt->option) + { + case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_SESSION_ID: + GNUNET_free (oph->session_id); + if (NULL != opt->details.session_id) + oph->session_id = GNUNET_strdup (opt->details.session_id); + break; + case TALER_MERCHANT_GET_PRIVATE_ORDER_OPTION_TIMEOUT: + oph->timeout = opt->details.timeout; + break; + default: + GNUNET_break (0); + return GNUNET_NO; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_order_start ( + struct TALER_MERCHANT_GetPrivateOrderHandle *oph, + TALER_MERCHANT_GetPrivateOrderCallback cb, + TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderMerchantGetHandle *omgh; + CURL *eh; unsigned int tms; - tms = (unsigned int) (timeout.rel_value_us + oph->cb = cb; + oph->cb_cls = cb_cls; + tms = (unsigned int) (oph->timeout.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us); - omgh = GNUNET_new (struct TALER_MERCHANT_OrderMerchantGetHandle); - omgh->ctx = ctx; - omgh->cb = cb; - omgh->cb_cls = cb_cls; { char *path; char timeout_ms[32]; @@ -467,72 +519,55 @@ TALER_MERCHANT_merchant_order_get ( tms); GNUNET_asprintf (&path, "private/orders/%s", - order_id); - omgh->url = TALER_url_join (backend_url, - path, - "session_id", session_id, - "timeout_ms", (0 != tms) ? timeout_ms : NULL, - NULL); + oph->order_id); + oph->url = TALER_url_join (oph->base_url, + path, + "session_id", + oph->session_id, + "timeout_ms", + (0 != tms) + ? timeout_ms + : NULL, + NULL); GNUNET_free (path); } - if (NULL == omgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (omgh); - return NULL; - } - + if (NULL == oph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (oph->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + if (0 != tms) { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (omgh->url); - if (NULL == eh) - { - GNUNET_break (0); - GNUNET_free (omgh->url); - GNUNET_free (omgh); - return NULL; - } - if (0 != tms) - { - GNUNET_break (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_TIMEOUT_MS, - (long) (tms + 100L))); - } - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Getting order status from %s\n", - omgh->url); - if (NULL == (omgh->job = - GNUNET_CURL_job_add (ctx, - eh, - &handle_merchant_order_get_finished, - omgh))) - { - GNUNET_break (0); - GNUNET_free (omgh->url); - GNUNET_free (omgh); - return NULL; - } + GNUNET_break (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_TIMEOUT_MS, + (long) (tms + 100L))); } - return omgh; + oph->job = GNUNET_CURL_job_add (oph->ctx, + eh, + &handle_get_private_order_finished, + oph); + if (NULL == oph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_merchant_order_get_cancel ( - struct TALER_MERCHANT_OrderMerchantGetHandle *omgh) +TALER_MERCHANT_get_private_order_cancel ( + struct TALER_MERCHANT_GetPrivateOrderHandle *oph) { - if (NULL != omgh->job) + if (NULL != oph->job) { - GNUNET_CURL_job_cancel (omgh->job); - omgh->job = NULL; + GNUNET_CURL_job_cancel (oph->job); + oph->job = NULL; } - GNUNET_free (omgh->url); - GNUNET_free (omgh); + GNUNET_free (oph->url); + GNUNET_free (oph->order_id); + GNUNET_free (oph->session_id); + GNUNET_free (oph->base_url); + GNUNET_free (oph); } -/* end of merchant_api_merchant_get_order.c */ +/* end of merchant_api_get-private-orders-ORDER_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-orders-new.c b/src/lib/merchant_api_get-private-orders-new.c @@ -1,522 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-orders-new.c - * @brief Implementation of the GET /private/orders request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-orders-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of orders we return. - */ -#define MAX_ORDERS 1024 - - -/** - * Handle for a GET /private/orders operation. - */ -struct TALER_MERCHANT_GetPrivateOrdersHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateOrdersCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Paid filter. - */ - enum TALER_EXCHANGE_YesNoAll paid; - - /** - * Refunded filter. - */ - enum TALER_EXCHANGE_YesNoAll refunded; - - /** - * Wired filter. - */ - enum TALER_EXCHANGE_YesNoAll wired; - - /** - * Date threshold for filtering. - */ - struct GNUNET_TIME_Timestamp date; - - /** - * Starting row for pagination. - */ - uint64_t offset; - - /** - * Limit on number of results. - */ - int64_t limit; - - /** - * Long polling timeout. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Session ID filter, or NULL. - */ - char *session_id; - - /** - * Fulfillment URL filter, or NULL. - */ - char *fulfillment_url; - - /** - * Summary text filter, or NULL. - */ - char *summary_filter; - - /** - * True if offset was explicitly set. - */ - bool have_offset; - - /** - * True if date was explicitly set. - */ - bool have_date; -}; - - -/** - * Parse order information from @a ia. - * - * @param ia JSON array (or NULL!) with order data - * @param[in,out] ogr response to fill - * @param oph operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_orders (const json_t *ia, - struct TALER_MERCHANT_GetPrivateOrdersResponse *ogr, - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph) -{ - unsigned int oes_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) oes_len) || - (oes_len > MAX_ORDERS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateOrdersOrderEntry oes[ - GNUNET_NZL (oes_len)]; - size_t index; - json_t *value; - - memset (oes, - 0, - sizeof (oes)); - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateOrdersOrderEntry *ie = &oes[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("order_id", - &ie->order_id), - GNUNET_JSON_spec_timestamp ("timestamp", - &ie->timestamp), - GNUNET_JSON_spec_uint64 ("row_id", - &ie->order_serial), - TALER_JSON_spec_amount_any ("amount", - &ie->amount), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount_any ("refund_amount", - &ie->refund_amount), - NULL), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount_any ("pending_refund_amount", - &ie->pending_refund_amount), - NULL), - GNUNET_JSON_spec_string ("summary", - &ie->summary), - GNUNET_JSON_spec_bool ("refundable", - &ie->refundable), - GNUNET_JSON_spec_bool ("paid", - &ie->paid), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - ogr->details.ok.orders_length = oes_len; - ogr->details.ok.orders = oes; - oph->cb (oph->cb_cls, - ogr); - oph->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/orders request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateOrdersHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_orders_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateOrdersResponse ogr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - oph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/orders response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *orders; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("orders", - &orders), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - ogr.hr.http_status = 0; - ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_orders (orders, - &ogr, - oph)) - { - TALER_MERCHANT_get_private_orders_cancel (oph); - return; - } - ogr.hr.http_status = 0; - ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ogr.hr.ec); - break; - } - oph->cb (oph->cb_cls, - &ogr); - TALER_MERCHANT_get_private_orders_cancel (oph); -} - - -struct TALER_MERCHANT_GetPrivateOrdersHandle * -TALER_MERCHANT_get_private_orders_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph; - - oph = GNUNET_new (struct TALER_MERCHANT_GetPrivateOrdersHandle); - oph->ctx = ctx; - oph->base_url = GNUNET_strdup (url); - oph->paid = TALER_EXCHANGE_YNA_ALL; - oph->refunded = TALER_EXCHANGE_YNA_ALL; - oph->wired = TALER_EXCHANGE_YNA_ALL; - oph->date = GNUNET_TIME_UNIT_FOREVER_TS; - oph->offset = UINT64_MAX; - oph->limit = -20; - return oph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_private_orders_set_options_ ( - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateOrdersOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - const struct TALER_MERCHANT_GetPrivateOrdersOptionValue *opt = - &options[i]; - - switch (opt->option) - { - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID: - oph->paid = opt->details.paid; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED: - oph->refunded = opt->details.refunded; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED: - oph->wired = opt->details.wired; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT: - oph->limit = opt->details.limit; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET: - oph->offset = opt->details.offset; - oph->have_offset = true; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE: - oph->date = opt->details.date; - oph->have_date = true; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT: - oph->timeout = opt->details.timeout; - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID: - GNUNET_free (oph->session_id); - if (NULL != opt->details.session_id) - oph->session_id = GNUNET_strdup (opt->details.session_id); - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL: - GNUNET_free (oph->fulfillment_url); - if (NULL != opt->details.fulfillment_url) - oph->fulfillment_url = GNUNET_strdup (opt->details.fulfillment_url); - break; - case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER: - GNUNET_free (oph->summary_filter); - if (NULL != opt->details.summary_filter) - oph->summary_filter = GNUNET_strdup (opt->details.summary_filter); - break; - default: - GNUNET_break (0); - return GNUNET_NO; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_orders_start ( - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, - TALER_MERCHANT_GetPrivateOrdersCallback cb, - TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - unsigned int tms; - - oph->cb = cb; - oph->cb_cls = cb_cls; - tms = (unsigned int) (oph->timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us); - { - char dstr[30]; - char *fec = NULL; - char *sid = NULL; - char *sfilt = NULL; - bool have_date; - bool have_srow; - char cbuf[30]; - char dbuf[30]; - char tbuf[30]; - - GNUNET_snprintf (tbuf, - sizeof (tbuf), - "%u", - tms); - GNUNET_snprintf (dbuf, - sizeof (dbuf), - "%lld", - (long long) oph->limit); - GNUNET_snprintf (cbuf, - sizeof (cbuf), - "%llu", - (unsigned long long) oph->offset); - if (NULL != oph->session_id) - (void) GNUNET_STRINGS_urlencode (strlen (oph->session_id), - oph->session_id, - &sid); - if (NULL != oph->fulfillment_url) - (void) GNUNET_STRINGS_urlencode (strlen (oph->fulfillment_url), - oph->fulfillment_url, - &fec); - if (NULL != oph->summary_filter) - (void) GNUNET_STRINGS_urlencode (strlen (oph->summary_filter), - oph->summary_filter, - &sfilt); - GNUNET_snprintf (dstr, - sizeof (dstr), - "%llu", - (unsigned long long) GNUNET_TIME_timestamp_to_s ( - oph->date)); - if (oph->limit > 0) - { - have_date = oph->have_date - && ! GNUNET_TIME_absolute_is_zero (oph->date.abs_time); - have_srow = oph->have_offset - && (0 != oph->offset); - } - else - { - have_date = oph->have_date - && ! GNUNET_TIME_absolute_is_never (oph->date.abs_time); - have_srow = oph->have_offset - && (UINT64_MAX != oph->offset); - } - oph->url = TALER_url_join (oph->base_url, - "private/orders", - "paid", - (TALER_EXCHANGE_YNA_ALL != oph->paid) - ? TALER_yna_to_string (oph->paid) - : NULL, - "refunded", - (TALER_EXCHANGE_YNA_ALL != oph->refunded) - ? TALER_yna_to_string (oph->refunded) - : NULL, - "wired", - (TALER_EXCHANGE_YNA_ALL != oph->wired) - ? TALER_yna_to_string (oph->wired) - : NULL, - "date_s", - have_date - ? dstr - : NULL, - "start", - have_srow - ? cbuf - : NULL, - "delta", - (-20 != oph->limit) - ? dbuf - : NULL, - "timeout_ms", - (0 != tms) - ? tbuf - : NULL, - "session_id", - sid, - "fulfillment_url", - fec, - "summary_filter", - sfilt, - NULL); - GNUNET_free (sid); - GNUNET_free (fec); - GNUNET_free (sfilt); - } - if (NULL == oph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (oph->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - if (0 != tms) - { - GNUNET_break (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_TIMEOUT_MS, - (long) (tms + 100L))); - } - oph->job = GNUNET_CURL_job_add (oph->ctx, - eh, - &handle_get_orders_finished, - oph); - if (NULL == oph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_orders_cancel ( - struct TALER_MERCHANT_GetPrivateOrdersHandle *oph) -{ - if (NULL != oph->job) - { - GNUNET_CURL_job_cancel (oph->job); - oph->job = NULL; - } - GNUNET_free (oph->url); - GNUNET_free (oph->session_id); - GNUNET_free (oph->fulfillment_url); - GNUNET_free (oph->summary_filter); - GNUNET_free (oph->base_url); - GNUNET_free (oph); -} - - -/* end of merchant_api_get-private-orders-new.c */ diff --git a/src/lib/merchant_api_get-private-orders.c b/src/lib/merchant_api_get-private-orders.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-orders.c - * @brief Implementation of the GET /private/orders request of the merchant's HTTP API + * @file merchant_api_get-private-orders-new.c + * @brief Implementation of the GET /private/orders request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,23 +25,29 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-orders.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> + /** * Maximum number of orders we return. */ #define MAX_ORDERS 1024 + /** - * Handle for a GET /orders operation. + * Handle for a GET /private/orders operation. */ -struct TALER_MERCHANT_OrdersGetHandle +struct TALER_MERCHANT_GetPrivateOrdersHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -53,18 +59,77 @@ struct TALER_MERCHANT_OrdersGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_OrdersGetCallback cb; + TALER_MERCHANT_GetPrivateOrdersCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Paid filter. + */ + enum TALER_EXCHANGE_YesNoAll paid; + + /** + * Refunded filter. + */ + enum TALER_EXCHANGE_YesNoAll refunded; + + /** + * Wired filter. + */ + enum TALER_EXCHANGE_YesNoAll wired; + + /** + * Date threshold for filtering. + */ + struct GNUNET_TIME_Timestamp date; + + /** + * Starting row for pagination. + */ + uint64_t offset; + + /** + * Limit on number of results. + */ + int64_t limit; + + /** + * Long polling timeout. + */ + struct GNUNET_TIME_Relative timeout; + + /** + * Session ID filter, or NULL. + */ + char *session_id; + + /** + * Fulfillment URL filter, or NULL. + */ + char *fulfillment_url; + + /** + * Summary text filter, or NULL. + */ + char *summary_filter; + + /** + * True if offset was explicitly set. + */ + bool have_offset; + + /** + * True if date was explicitly set. + */ + bool have_date; }; @@ -72,25 +137,26 @@ struct TALER_MERCHANT_OrdersGetHandle * Parse order information from @a ia. * * @param ia JSON array (or NULL!) with order data - * @param[in] ogr response to fill - * @param ogh operation handle + * @param[in,out] ogr response to fill + * @param oph operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_orders (const json_t *ia, - struct TALER_MERCHANT_OrdersGetResponse *ogr, - struct TALER_MERCHANT_OrdersGetHandle *ogh) + struct TALER_MERCHANT_GetPrivateOrdersResponse *ogr, + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph) { unsigned int oes_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) oes_len) || + if ( (json_array_size (ia) != (size_t) oes_len) || (oes_len > MAX_ORDERS) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_OrderEntry oes[GNUNET_NZL (oes_len)]; + struct TALER_MERCHANT_GetPrivateOrdersOrderEntry oes[ + GNUNET_NZL (oes_len)]; size_t index; json_t *value; @@ -98,7 +164,7 @@ parse_orders (const json_t *ia, 0, sizeof (oes)); json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_OrderEntry *ie = &oes[index]; + struct TALER_MERCHANT_GetPrivateOrdersOrderEntry *ie = &oes[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("order_id", &ie->order_id), @@ -136,9 +202,9 @@ parse_orders (const json_t *ia, } ogr->details.ok.orders_length = oes_len; ogr->details.ok.orders = oes; - ogh->cb (ogh->cb_cls, + oph->cb (oph->cb_cls, ogr); - ogh->cb = NULL; /* just to be sure */ + oph->cb = NULL; } return GNUNET_OK; } @@ -146,9 +212,9 @@ parse_orders (const json_t *ia, /** * Function called when we're done processing the - * HTTP /orders request. + * HTTP GET /private/orders request. * - * @param cls the `struct TALER_MERCHANT_OrdersGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateOrdersHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -157,16 +223,16 @@ handle_get_orders_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrdersGetHandle *ogh = cls; + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph = cls; const json_t *json = response; - struct TALER_MERCHANT_OrdersGetResponse ogr = { + struct TALER_MERCHANT_GetPrivateOrdersResponse ogr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - ogh->job = NULL; + oph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /orders response with status code %u\n", + "Got /private/orders response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -191,9 +257,9 @@ handle_get_orders_finished (void *cls, if (GNUNET_OK == parse_orders (orders, &ogr, - ogh)) + oph)) { - TALER_MERCHANT_orders_get_cancel (ogh); + TALER_MERCHANT_get_private_orders_cancel (oph); return; } ogr.hr.http_status = 0; @@ -203,14 +269,12 @@ handle_get_orders_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: ogr.hr.ec = TALER_JSON_get_error_code (json); ogr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: ogr.hr.ec = TALER_JSON_get_error_code (json); ogr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ ogr.hr.ec = TALER_JSON_get_error_code (json); ogr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -219,107 +283,112 @@ handle_get_orders_finished (void *cls, (int) ogr.hr.ec); break; } - ogh->cb (ogh->cb_cls, + oph->cb (oph->cb_cls, &ogr); - TALER_MERCHANT_orders_get_cancel (ogh); + TALER_MERCHANT_get_private_orders_cancel (oph); } -struct TALER_MERCHANT_OrdersGetHandle * -TALER_MERCHANT_orders_get ( +struct TALER_MERCHANT_GetPrivateOrdersHandle * +TALER_MERCHANT_get_private_orders_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_OrdersGetCallback cb, - void *cb_cls) + const char *url) { - return TALER_MERCHANT_orders_get2 (ctx, - backend_url, - TALER_EXCHANGE_YNA_ALL, - TALER_EXCHANGE_YNA_ALL, - TALER_EXCHANGE_YNA_ALL, - GNUNET_TIME_UNIT_FOREVER_TS, - UINT64_MAX, - -20, /* default is most recent 20 entries */ - GNUNET_TIME_UNIT_ZERO, - cb, - cb_cls); + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph; + + oph = GNUNET_new (struct TALER_MERCHANT_GetPrivateOrdersHandle); + oph->ctx = ctx; + oph->base_url = GNUNET_strdup (url); + oph->paid = TALER_EXCHANGE_YNA_ALL; + oph->refunded = TALER_EXCHANGE_YNA_ALL; + oph->wired = TALER_EXCHANGE_YNA_ALL; + oph->date = GNUNET_TIME_UNIT_FOREVER_TS; + oph->offset = UINT64_MAX; + oph->limit = -20; + return oph; } -struct TALER_MERCHANT_OrdersGetHandle * -TALER_MERCHANT_orders_get2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - enum TALER_EXCHANGE_YesNoAll paid, - enum TALER_EXCHANGE_YesNoAll refunded, - enum TALER_EXCHANGE_YesNoAll wired, - struct GNUNET_TIME_Timestamp date, - uint64_t start_row, - int64_t delta, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_OrdersGetCallback cb, - void *cb_cls) +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_orders_set_options_ ( + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateOrdersOptionValue *options) { - return TALER_MERCHANT_orders_get3 ( - ctx, - backend_url, - paid, - refunded, - wired, - NULL, - NULL, - date, - start_row, - delta, - timeout, - cb, - cb_cls); + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_MERCHANT_GetPrivateOrdersOptionValue *opt = + &options[i]; + + switch (opt->option) + { + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_PAID: + oph->paid = opt->details.paid; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_REFUNDED: + oph->refunded = opt->details.refunded; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_WIRED: + oph->wired = opt->details.wired; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_LIMIT: + oph->limit = opt->details.limit; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_OFFSET: + oph->offset = opt->details.offset; + oph->have_offset = true; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_DATE: + oph->date = opt->details.date; + oph->have_date = true; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_TIMEOUT: + oph->timeout = opt->details.timeout; + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SESSION_ID: + GNUNET_free (oph->session_id); + if (NULL != opt->details.session_id) + oph->session_id = GNUNET_strdup (opt->details.session_id); + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_FULFILLMENT_URL: + GNUNET_free (oph->fulfillment_url); + if (NULL != opt->details.fulfillment_url) + oph->fulfillment_url = GNUNET_strdup (opt->details.fulfillment_url); + break; + case TALER_MERCHANT_GET_PRIVATE_ORDERS_OPTION_SUMMARY_FILTER: + GNUNET_free (oph->summary_filter); + if (NULL != opt->details.summary_filter) + oph->summary_filter = GNUNET_strdup (opt->details.summary_filter); + break; + default: + GNUNET_break (0); + return GNUNET_NO; + } + } + return GNUNET_OK; } -struct TALER_MERCHANT_OrdersGetHandle * -TALER_MERCHANT_orders_get3 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - enum TALER_EXCHANGE_YesNoAll paid, - enum TALER_EXCHANGE_YesNoAll refunded, - enum TALER_EXCHANGE_YesNoAll wired, - const char *session_id, - const char *fulfillment_url, - struct GNUNET_TIME_Timestamp date, - uint64_t start_row, - int64_t delta, - struct GNUNET_TIME_Relative timeout, - TALER_MERCHANT_OrdersGetCallback cb, - void *cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_get_private_orders_start ( + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph, + TALER_MERCHANT_GetPrivateOrdersCallback cb, + TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrdersGetHandle *ogh; CURL *eh; - unsigned int tms = timeout.rel_value_us - / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; - - GNUNET_assert (NULL != backend_url); - if ( (delta > MAX_ORDERS) || - (delta < -MAX_ORDERS) ) - { - GNUNET_break (0); - return NULL; - } - if (0 == delta) - { - GNUNET_break (0); - return NULL; - } - ogh = GNUNET_new (struct TALER_MERCHANT_OrdersGetHandle); - ogh->ctx = ctx; - ogh->cb = cb; - ogh->cb_cls = cb_cls; + unsigned int tms; - /* build ogh->url with the various optional arguments */ + oph->cb = cb; + oph->cb_cls = cb_cls; + tms = (unsigned int) (oph->timeout.rel_value_us + / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us); { char dstr[30]; char *fec = NULL; char *sid = NULL; + char *sfilt = NULL; bool have_date; bool have_srow; char cbuf[30]; @@ -333,57 +402,66 @@ TALER_MERCHANT_orders_get3 ( GNUNET_snprintf (dbuf, sizeof (dbuf), "%lld", - (long long) delta); + (long long) oph->limit); GNUNET_snprintf (cbuf, sizeof (cbuf), "%llu", - (unsigned long long) start_row); - if (NULL != session_id) - (void) GNUNET_STRINGS_urlencode (strlen (session_id), - session_id, + (unsigned long long) oph->offset); + if (NULL != oph->session_id) + (void) GNUNET_STRINGS_urlencode (strlen (oph->session_id), + oph->session_id, &sid); - if (NULL != fulfillment_url) - (void) GNUNET_STRINGS_urlencode (strlen (fulfillment_url), - fulfillment_url, + if (NULL != oph->fulfillment_url) + (void) GNUNET_STRINGS_urlencode (strlen (oph->fulfillment_url), + oph->fulfillment_url, &fec); + if (NULL != oph->summary_filter) + (void) GNUNET_STRINGS_urlencode (strlen (oph->summary_filter), + oph->summary_filter, + &sfilt); GNUNET_snprintf (dstr, sizeof (dstr), "%llu", - (unsigned long long) GNUNET_TIME_timestamp_to_s (date)); - if (delta > 0) + (unsigned long long) GNUNET_TIME_timestamp_to_s ( + oph->date)); + if (oph->limit > 0) { - have_date = ! GNUNET_TIME_absolute_is_zero (date.abs_time); - have_srow = (0 != start_row); + have_date = oph->have_date + && ! GNUNET_TIME_absolute_is_zero (oph->date.abs_time); + have_srow = oph->have_offset + && (0 != oph->offset); } else { - have_date = ! GNUNET_TIME_absolute_is_never (date.abs_time); - have_srow = (UINT64_MAX != start_row); + have_date = oph->have_date + && ! GNUNET_TIME_absolute_is_never (oph->date.abs_time); + have_srow = oph->have_offset + && (UINT64_MAX != oph->offset); } - ogh->url = TALER_url_join (backend_url, + oph->url = TALER_url_join (oph->base_url, "private/orders", "paid", - (TALER_EXCHANGE_YNA_ALL != paid) - ? TALER_yna_to_string (paid) + (TALER_EXCHANGE_YNA_ALL != oph->paid) + ? TALER_yna_to_string (oph->paid) : NULL, "refunded", - (TALER_EXCHANGE_YNA_ALL != refunded) - ? TALER_yna_to_string (refunded) + (TALER_EXCHANGE_YNA_ALL != oph->refunded) + ? TALER_yna_to_string (oph->refunded) : NULL, "wired", - (TALER_EXCHANGE_YNA_ALL != wired) - ? TALER_yna_to_string (wired) + (TALER_EXCHANGE_YNA_ALL != oph->wired) + ? TALER_yna_to_string (oph->wired) : NULL, "date_s", - (have_date) + have_date ? dstr : NULL, "start", - (have_srow) + have_srow ? cbuf : NULL, "delta", - (-20 != delta) + (-20 != oph->limit) ? dbuf : NULL, "timeout_ms", @@ -394,28 +472,18 @@ TALER_MERCHANT_orders_get3 ( sid, "fulfillment_url", fec, + "summary_filter", + sfilt, NULL); GNUNET_free (sid); GNUNET_free (fec); + GNUNET_free (sfilt); } - if (NULL == ogh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (ogh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - ogh->url); - eh = TALER_MERCHANT_curl_easy_get_ (ogh->url); + if (NULL == oph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (oph->url); if (NULL == eh) - { - GNUNET_break (0); - GNUNET_free (ogh->url); - GNUNET_free (ogh); - return NULL; - } + return TALER_EC_GENERIC_CONFIGURATION_INVALID; if (0 != tms) { GNUNET_break (CURLE_OK == @@ -423,20 +491,32 @@ TALER_MERCHANT_orders_get3 ( CURLOPT_TIMEOUT_MS, (long) (tms + 100L))); } - ogh->job = GNUNET_CURL_job_add (ctx, + oph->job = GNUNET_CURL_job_add (oph->ctx, eh, &handle_get_orders_finished, - ogh); - return ogh; + oph); + if (NULL == oph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_orders_get_cancel ( - struct TALER_MERCHANT_OrdersGetHandle *ogh) +TALER_MERCHANT_get_private_orders_cancel ( + struct TALER_MERCHANT_GetPrivateOrdersHandle *oph) { - if (NULL != ogh->job) - GNUNET_CURL_job_cancel (ogh->job); - GNUNET_free (ogh->url); - GNUNET_free (ogh); + if (NULL != oph->job) + { + GNUNET_CURL_job_cancel (oph->job); + oph->job = NULL; + } + GNUNET_free (oph->url); + GNUNET_free (oph->session_id); + GNUNET_free (oph->fulfillment_url); + GNUNET_free (oph->summary_filter); + GNUNET_free (oph->base_url); + GNUNET_free (oph); } + + +/* end of merchant_api_get-private-orders-new.c */ diff --git a/src/lib/merchant_api_get-private-otp-devices-DEVICE_ID-new.c b/src/lib/merchant_api_get-private-otp-devices-DEVICE_ID-new.c @@ -1,231 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-otp-devices-DEVICE_ID-new.c - * @brief Implementation of the GET /private/otp-devices/$DEVICE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/otp-devices/$DEVICE_ID operation. - */ -struct TALER_MERCHANT_GetPrivateOtpDeviceHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * OTP device identifier. - */ - char *otp_device_id; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateOtpDeviceCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /private/otp-devices/$DEVICE_ID request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateOtpDeviceHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_otp_device_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateOtpDeviceResponse ogr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - god->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/otp-devices/$DEVICE_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - uint32_t alg32; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("otp_device_description", - &ogr.details.ok.otp_device_description), - GNUNET_JSON_spec_uint32 ("otp_algorithm", - &alg32), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint64 ("otp_ctr", - &ogr.details.ok.otp_ctr), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint64 ("otp_timestamp", - &ogr.details.ok.otp_timestamp_s), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("otp_code", - &ogr.details.ok.otp_code), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - ogr.details.ok.otp_alg = - (enum TALER_MerchantConfirmationAlgorithm) alg32; - god->cb (god->cb_cls, - &ogr); - TALER_MERCHANT_get_private_otp_device_cancel (god); - return; - } - ogr.hr.http_status = 0; - ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ogr.hr.ec); - break; - } - god->cb (god->cb_cls, - &ogr); - TALER_MERCHANT_get_private_otp_device_cancel (god); -} - - -struct TALER_MERCHANT_GetPrivateOtpDeviceHandle * -TALER_MERCHANT_get_private_otp_device_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id) -{ - struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god; - - god = GNUNET_new (struct TALER_MERCHANT_GetPrivateOtpDeviceHandle); - god->ctx = ctx; - god->base_url = GNUNET_strdup (url); - god->otp_device_id = GNUNET_strdup (otp_device_id); - return god; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_otp_device_start ( - struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, - TALER_MERCHANT_GetPrivateOtpDeviceCallback cb, - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - god->cb = cb; - god->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/otp-devices/%s", - god->otp_device_id); - god->url = TALER_url_join (god->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == god->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (god->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - god->job = GNUNET_CURL_job_add (god->ctx, - eh, - &handle_get_otp_device_finished, - god); - if (NULL == god->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_otp_device_cancel ( - struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god) -{ - if (NULL != god->job) - { - GNUNET_CURL_job_cancel (god->job); - god->job = NULL; - } - GNUNET_free (god->url); - GNUNET_free (god->otp_device_id); - GNUNET_free (god->base_url); - GNUNET_free (god); -} - - -/* end of merchant_api_get-private-otp-devices-DEVICE_ID-new.c */ 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 @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-otp-devices-DEVICE_ID.c - * @brief Implementation of the GET /otp-devices/$ID request of the merchant's HTTP API + * @file merchant_api_get-private-otp-devices-DEVICE_ID-new.c + * @brief Implementation of the GET /private/otp-devices/$DEVICE_ID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,28 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /otp-devices/$ID operation. + * Handle for a GET /private/otp-devices/$DEVICE_ID operation. */ -struct TALER_MERCHANT_OtpDeviceGetHandle +struct TALER_MERCHANT_GetPrivateOtpDeviceHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * OTP device identifier. + */ + char *otp_device_id; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +58,25 @@ struct TALER_MERCHANT_OtpDeviceGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_OtpDeviceGetCallback cb; + TALER_MERCHANT_GetPrivateOtpDeviceCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Function called when we're done processing the - * HTTP GET /otp-devices/$ID request. + * HTTP GET /private/otp-devices/$DEVICE_ID request. * - * @param cls the `struct TALER_MERCHANT_OtpDeviceGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateOtpDeviceHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,16 +85,16 @@ handle_get_otp_device_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OtpDeviceGetHandle *tgh = cls; + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god = cls; const json_t *json = response; - struct TALER_MERCHANT_OtpDeviceGetResponse tgr = { + struct TALER_MERCHANT_GetPrivateOtpDeviceResponse ogr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + god->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /otp-devices/$ID response with status code %u\n", + "Got /private/otp-devices/$DEVICE_ID response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -95,20 +103,20 @@ handle_get_otp_device_finished (void *cls, uint32_t alg32; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("otp_device_description", - &tgr.details.ok.otp_device_description), + &ogr.details.ok.otp_device_description), GNUNET_JSON_spec_uint32 ("otp_algorithm", &alg32), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint64 ("otp_ctr", - &tgr.details.ok.otp_ctr), + &ogr.details.ok.otp_ctr), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint64 ("otp_timestamp", - &tgr.details.ok.otp_timestamp_s), + &ogr.details.ok.otp_timestamp_s), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("otp_code", - &tgr.details.ok.otp_code), + &ogr.details.ok.otp_code), NULL), GNUNET_JSON_spec_end () }; @@ -118,93 +126,106 @@ handle_get_otp_device_finished (void *cls, spec, NULL, NULL)) { - tgr.details.ok.otp_alg = + ogr.details.ok.otp_alg = (enum TALER_MerchantConfirmationAlgorithm) alg32; - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_otp_device_get_cancel (tgh); + god->cb (god->cb_cls, + &ogr); + TALER_MERCHANT_get_private_otp_device_cancel (god); return; } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ogr.hr.http_status = 0; + ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + ogr.hr.ec = TALER_JSON_get_error_code (json); + ogr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + ogr.hr.ec = TALER_JSON_get_error_code (json); + ogr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + ogr.hr.ec = TALER_JSON_get_error_code (json); + ogr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) tgr.hr.ec); + (int) ogr.hr.ec); break; } - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_otp_device_get_cancel (tgh); + god->cb (god->cb_cls, + &ogr); + TALER_MERCHANT_get_private_otp_device_cancel (god); } -struct TALER_MERCHANT_OtpDeviceGetHandle * -TALER_MERCHANT_otp_device_get ( +struct TALER_MERCHANT_GetPrivateOtpDeviceHandle * +TALER_MERCHANT_get_private_otp_device_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *otp_device_id, - TALER_MERCHANT_OtpDeviceGetCallback cb, - void *cb_cls) + const char *url, + const char *otp_device_id) +{ + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god; + + god = GNUNET_new (struct TALER_MERCHANT_GetPrivateOtpDeviceHandle); + god->ctx = ctx; + god->base_url = GNUNET_strdup (url); + god->otp_device_id = GNUNET_strdup (otp_device_id); + return god; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_otp_device_start ( + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god, + TALER_MERCHANT_GetPrivateOtpDeviceCallback cb, + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OtpDeviceGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_OtpDeviceGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; + god->cb = cb; + god->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/otp-devices/%s", - otp_device_id); - tgh->url = TALER_url_join (backend_url, + god->otp_device_id); + god->url = TALER_url_join (god->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == god->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (god->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + god->job = GNUNET_CURL_job_add (god->ctx, eh, &handle_get_otp_device_finished, - tgh); - return tgh; + god); + if (NULL == god->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_otp_device_get_cancel ( - struct TALER_MERCHANT_OtpDeviceGetHandle *tgh) +TALER_MERCHANT_get_private_otp_device_cancel ( + struct TALER_MERCHANT_GetPrivateOtpDeviceHandle *god) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != god->job) + { + GNUNET_CURL_job_cancel (god->job); + god->job = NULL; + } + GNUNET_free (god->url); + GNUNET_free (god->otp_device_id); + GNUNET_free (god->base_url); + GNUNET_free (god); } + + +/* end of merchant_api_get-private-otp-devices-DEVICE_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-otp-devices-new.c b/src/lib/merchant_api_get-private-otp-devices-new.c @@ -1,264 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-otp-devices-new.c - * @brief Implementation of the GET /private/otp-devices request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-otp-devices-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - -/** - * Maximum number of OTP devices we return. - */ -#define MAX_OTP 1024 - - -/** - * Handle for a GET /private/otp-devices operation. - */ -struct TALER_MERCHANT_GetPrivateOtpDevicesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateOtpDevicesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse OTP device information from @a ia. - * - * @param ia JSON array (or NULL!) with otp_device data - * @param[in] ogr partially filled response - * @param gpoh operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_otp_devices (const json_t *ia, - struct TALER_MERCHANT_GetPrivateOtpDevicesResponse *ogr, - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh) -{ - unsigned int otp_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) otp_len) || - (otp_len > MAX_OTP) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry otp[ - GNUNET_NZL (otp_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry *ie = - &otp[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("otp_device_id", - &ie->otp_device_id), - GNUNET_JSON_spec_string ("device_description", - &ie->otp_device_description), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - ogr->details.ok.otp_devices_length = otp_len; - ogr->details.ok.otp_devices = otp; - gpoh->cb (gpoh->cb_cls, - ogr); - gpoh->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/otp-devices request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateOtpDevicesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_otp_devices_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateOtpDevicesResponse ogr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpoh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/otp-devices response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *otp_devices; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("otp_devices", - &otp_devices), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - ogr.hr.http_status = 0; - ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_otp_devices (otp_devices, - &ogr, - gpoh)) - { - TALER_MERCHANT_get_private_otp_devices_cancel (gpoh); - return; - } - ogr.hr.http_status = 0; - ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - ogr.hr.ec = TALER_JSON_get_error_code (json); - ogr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ogr.hr.ec); - break; - } - gpoh->cb (gpoh->cb_cls, - &ogr); - TALER_MERCHANT_get_private_otp_devices_cancel (gpoh); -} - - -struct TALER_MERCHANT_GetPrivateOtpDevicesHandle * -TALER_MERCHANT_get_private_otp_devices_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh; - - gpoh = GNUNET_new (struct TALER_MERCHANT_GetPrivateOtpDevicesHandle); - gpoh->ctx = ctx; - gpoh->base_url = GNUNET_strdup (url); - return gpoh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_otp_devices_start ( - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh, - TALER_MERCHANT_GetPrivateOtpDevicesCallback cb, - TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpoh->cb = cb; - gpoh->cb_cls = cb_cls; - gpoh->url = TALER_url_join (gpoh->base_url, - "private/otp-devices", - NULL); - if (NULL == gpoh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpoh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpoh->job = GNUNET_CURL_job_add (gpoh->ctx, - eh, - &handle_get_otp_devices_finished, - gpoh); - if (NULL == gpoh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_otp_devices_cancel ( - struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh) -{ - if (NULL != gpoh->job) - { - GNUNET_CURL_job_cancel (gpoh->job); - gpoh->job = NULL; - } - GNUNET_free (gpoh->url); - GNUNET_free (gpoh->base_url); - GNUNET_free (gpoh); -} - - -/* end of merchant_api_get-private-otp-devices-new.c */ diff --git a/src/lib/merchant_api_get-private-otp-devices.c b/src/lib/merchant_api_get-private-otp-devices.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-otp-devices.c - * @brief Implementation of the GET /otp-devices request of the merchant's HTTP API + * @file merchant_api_get-private-otp-devices-new.c + * @brief Implementation of the GET /private/otp-devices request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,10 +25,9 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-otp-devices.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** * Maximum number of OTP devices we return. @@ -37,12 +36,17 @@ /** - * Handle for a GET /otp-devices operation. + * Handle for a GET /private/otp-devices operation. */ -struct TALER_MERCHANT_OtpDevicesGetHandle +struct TALER_MERCHANT_GetPrivateOtpDevicesHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -54,18 +58,17 @@ struct TALER_MERCHANT_OtpDevicesGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_OtpDevicesGetCallback cb; + TALER_MERCHANT_GetPrivateOtpDevicesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; @@ -73,30 +76,32 @@ struct TALER_MERCHANT_OtpDevicesGetHandle * Parse OTP device information from @a ia. * * @param ia JSON array (or NULL!) with otp_device data - * @param[in] tgr partially filled response - * @param tgh operation handle + * @param[in] ogr partially filled response + * @param gpoh operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_otp_devices (const json_t *ia, - struct TALER_MERCHANT_OtpDevicesGetResponse *tgr, - struct TALER_MERCHANT_OtpDevicesGetHandle *tgh) + struct TALER_MERCHANT_GetPrivateOtpDevicesResponse *ogr, + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh) { unsigned int otp_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) otp_len) || + if ( (json_array_size (ia) != (size_t) otp_len) || (otp_len > MAX_OTP) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_OtpDeviceEntry otp[GNUNET_NZL (otp_len)]; + struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry otp[ + GNUNET_NZL (otp_len)]; size_t index; json_t *value; json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_OtpDeviceEntry *ie = &otp[index]; + struct TALER_MERCHANT_GetPrivateOtpDevicesOtpDeviceEntry *ie = + &otp[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("otp_device_id", &ie->otp_device_id), @@ -114,11 +119,11 @@ parse_otp_devices (const json_t *ia, return GNUNET_SYSERR; } } - tgr->details.ok.otp_devices_length = otp_len; - tgr->details.ok.otp_devices = otp; - tgh->cb (tgh->cb_cls, - tgr); - tgh->cb = NULL; /* just to be sure */ + ogr->details.ok.otp_devices_length = otp_len; + ogr->details.ok.otp_devices = otp; + gpoh->cb (gpoh->cb_cls, + ogr); + gpoh->cb = NULL; } return GNUNET_OK; } @@ -126,9 +131,9 @@ parse_otp_devices (const json_t *ia, /** * Function called when we're done processing the - * HTTP /otp-devices request. + * HTTP GET /private/otp-devices request. * - * @param cls the `struct TALER_MERCHANT_OtpDevicesGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateOtpDevicesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -137,16 +142,16 @@ handle_get_otp_devices_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OtpDevicesGetHandle *tgh = cls; + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh = cls; const json_t *json = response; - struct TALER_MERCHANT_OtpDevicesGetResponse tgr = { + struct TALER_MERCHANT_GetPrivateOtpDevicesResponse ogr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + gpoh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /otp-devices response with status code %u\n", + "Got /private/otp-devices response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -164,85 +169,96 @@ handle_get_otp_devices_finished (void *cls, spec, NULL, NULL)) { - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ogr.hr.http_status = 0; + ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } if (GNUNET_OK == parse_otp_devices (otp_devices, - &tgr, - tgh)) + &ogr, + gpoh)) { - TALER_MERCHANT_otp_devices_get_cancel (tgh); + TALER_MERCHANT_get_private_otp_devices_cancel (gpoh); return; } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ogr.hr.http_status = 0; + ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + ogr.hr.ec = TALER_JSON_get_error_code (json); + ogr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + ogr.hr.ec = TALER_JSON_get_error_code (json); + ogr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) tgr.hr.ec); + (int) ogr.hr.ec); break; } - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_otp_devices_get_cancel (tgh); + gpoh->cb (gpoh->cb_cls, + &ogr); + TALER_MERCHANT_get_private_otp_devices_cancel (gpoh); } -struct TALER_MERCHANT_OtpDevicesGetHandle * -TALER_MERCHANT_otp_devices_get ( +struct TALER_MERCHANT_GetPrivateOtpDevicesHandle * +TALER_MERCHANT_get_private_otp_devices_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_OtpDevicesGetCallback cb, - void *cb_cls) + const char *url) +{ + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh; + + gpoh = GNUNET_new (struct TALER_MERCHANT_GetPrivateOtpDevicesHandle); + gpoh->ctx = ctx; + gpoh->base_url = GNUNET_strdup (url); + return gpoh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_otp_devices_start ( + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh, + TALER_MERCHANT_GetPrivateOtpDevicesCallback cb, + TALER_MERCHANT_GET_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OtpDevicesGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_OtpDevicesGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; - tgh->url = TALER_url_join (backend_url, - "private/otp-devices", - NULL); - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_otp_devices_finished, - tgh); - return tgh; + gpoh->cb = cb; + gpoh->cb_cls = cb_cls; + gpoh->url = TALER_url_join (gpoh->base_url, + "private/otp-devices", + NULL); + if (NULL == gpoh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpoh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpoh->job = GNUNET_CURL_job_add (gpoh->ctx, + eh, + &handle_get_otp_devices_finished, + gpoh); + if (NULL == gpoh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_otp_devices_get_cancel ( - struct TALER_MERCHANT_OtpDevicesGetHandle *tgh) +TALER_MERCHANT_get_private_otp_devices_cancel ( + struct TALER_MERCHANT_GetPrivateOtpDevicesHandle *gpoh) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != gpoh->job) + { + GNUNET_CURL_job_cancel (gpoh->job); + gpoh->job = NULL; + } + GNUNET_free (gpoh->url); + GNUNET_free (gpoh->base_url); + GNUNET_free (gpoh); } + + +/* end of merchant_api_get-private-otp-devices-new.c */ diff --git a/src/lib/merchant_api_get-private-products-PRODUCT_ID-new.c b/src/lib/merchant_api_get-private-products-PRODUCT_ID-new.c @@ -1,270 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-products-PRODUCT_ID-new.c - * @brief Implementation of the GET /private/products/$PRODUCT_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-products-PRODUCT_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/products/$PRODUCT_ID operation. - */ -struct TALER_MERCHANT_GetPrivateProductHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * Product identifier. - */ - char *product_id; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateProductCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /private/products/$PRODUCT_ID request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateProductHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_product_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateProductHandle *gpp = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateProductResponse pgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpp->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/products/$PRODUCT_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ( - "product_name", - &pgr.details.ok.product_name), - GNUNET_JSON_spec_string ( - "description", - &pgr.details.ok.description), - GNUNET_JSON_spec_object_const ( - "description_i18n", - &pgr.details.ok.description_i18n), - GNUNET_JSON_spec_string ( - "unit", - &pgr.details.ok.unit), - TALER_JSON_spec_amount_any_array ( - "unit_price", - &pgr.details.ok.unit_price_len, - (struct TALER_Amount **) &pgr.details.ok.unit_price), - TALER_JSON_spec_amount_any ( - "price", - &pgr.details.ok.price), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ( - "image", - &pgr.details.ok.image), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ( - "taxes", - &pgr.details.ok.taxes), - NULL), - GNUNET_JSON_spec_int64 ( - "total_stock", - &pgr.details.ok.total_stock), - GNUNET_JSON_spec_string ( - "unit_total_stock", - &pgr.details.ok.unit_total_stock), - GNUNET_JSON_spec_bool ( - "unit_allow_fraction", - &pgr.details.ok.unit_allow_fraction), - GNUNET_JSON_spec_uint32 ( - "unit_precision_level", - &pgr.details.ok.unit_precision_level), - GNUNET_JSON_spec_uint64 ( - "total_sold", - &pgr.details.ok.total_sold), - GNUNET_JSON_spec_uint64 ( - "total_lost", - &pgr.details.ok.total_lost), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ( - "address", - &pgr.details.ok.location), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ( - "next_restock", - &pgr.details.ok.next_restock), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - gpp->cb (gpp->cb_cls, - &pgr); - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_get_private_product_cancel (gpp); - return; - } - pgr.hr.http_status = 0; - pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pgr.hr.ec); - break; - } - gpp->cb (gpp->cb_cls, - &pgr); - TALER_MERCHANT_get_private_product_cancel (gpp); -} - - -struct TALER_MERCHANT_GetPrivateProductHandle * -TALER_MERCHANT_get_private_product_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id) -{ - struct TALER_MERCHANT_GetPrivateProductHandle *gpp; - - gpp = GNUNET_new (struct TALER_MERCHANT_GetPrivateProductHandle); - gpp->ctx = ctx; - gpp->base_url = GNUNET_strdup (url); - gpp->product_id = GNUNET_strdup (product_id); - return gpp; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_product_start ( - struct TALER_MERCHANT_GetPrivateProductHandle *gpp, - TALER_MERCHANT_GetPrivateProductCallback cb, - TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpp->cb = cb; - gpp->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/products/%s", - gpp->product_id); - gpp->url = TALER_url_join (gpp->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gpp->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpp->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpp->job = GNUNET_CURL_job_add (gpp->ctx, - eh, - &handle_get_product_finished, - gpp); - if (NULL == gpp->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_product_cancel ( - struct TALER_MERCHANT_GetPrivateProductHandle *gpp) -{ - if (NULL != gpp->job) - { - GNUNET_CURL_job_cancel (gpp->job); - gpp->job = NULL; - } - GNUNET_free (gpp->url); - GNUNET_free (gpp->product_id); - GNUNET_free (gpp->base_url); - GNUNET_free (gpp); -} - - -/* end of merchant_api_get-private-products-PRODUCT_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-products-PRODUCT_ID.c b/src/lib/merchant_api_get-private-products-PRODUCT_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014--2025 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-products-PRODUCT_ID.c - * @brief Implementation of the GET /product/$ID request of the merchant's HTTP API + * @file merchant_api_get-private-products-PRODUCT_ID-new.c + * @brief Implementation of the GET /private/products/$PRODUCT_ID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,19 +25,28 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-products-PRODUCT_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /products/$ID operation. + * Handle for a GET /private/products/$PRODUCT_ID operation. */ -struct TALER_MERCHANT_ProductGetHandle +struct TALER_MERCHANT_GetPrivateProductHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * Product identifier. + */ + char *product_id; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +58,25 @@ struct TALER_MERCHANT_ProductGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductGetCallback cb; + TALER_MERCHANT_GetPrivateProductCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Function called when we're done processing the - * HTTP GET /products/$ID request. + * HTTP GET /private/products/$PRODUCT_ID request. * - * @param cls the `struct TALER_MERCHANT_ProductGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateProductHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,16 +85,16 @@ handle_get_product_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_ProductGetHandle *pgh = cls; + struct TALER_MERCHANT_GetPrivateProductHandle *gpp = cls; const json_t *json = response; - struct TALER_MERCHANT_ProductGetResponse pgr = { + struct TALER_MERCHANT_GetPrivateProductResponse pgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - pgh->job = NULL; + gpp->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /products/$ID response with status code %u\n", + "Got /private/products/$PRODUCT_ID response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -158,10 +166,10 @@ handle_get_product_finished (void *cls, spec, NULL, NULL)) { - pgh->cb (pgh->cb_cls, + gpp->cb (gpp->cb_cls, &pgr); GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_product_get_cancel (pgh); + TALER_MERCHANT_get_private_product_cancel (gpp); return; } pgr.hr.http_status = 0; @@ -171,14 +179,12 @@ handle_get_product_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: pgr.hr.ec = TALER_JSON_get_error_code (json); pgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: pgr.hr.ec = TALER_JSON_get_error_code (json); pgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ pgr.hr.ec = TALER_JSON_get_error_code (json); pgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -187,63 +193,78 @@ handle_get_product_finished (void *cls, (int) pgr.hr.ec); break; } - pgh->cb (pgh->cb_cls, + gpp->cb (gpp->cb_cls, &pgr); - TALER_MERCHANT_product_get_cancel (pgh); + TALER_MERCHANT_get_private_product_cancel (gpp); } -struct TALER_MERCHANT_ProductGetHandle * -TALER_MERCHANT_product_get ( +struct TALER_MERCHANT_GetPrivateProductHandle * +TALER_MERCHANT_get_private_product_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - TALER_MERCHANT_ProductGetCallback cb, - void *cb_cls) + const char *url, + const char *product_id) +{ + struct TALER_MERCHANT_GetPrivateProductHandle *gpp; + + gpp = GNUNET_new (struct TALER_MERCHANT_GetPrivateProductHandle); + gpp->ctx = ctx; + gpp->base_url = GNUNET_strdup (url); + gpp->product_id = GNUNET_strdup (product_id); + return gpp; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_product_start ( + struct TALER_MERCHANT_GetPrivateProductHandle *gpp, + TALER_MERCHANT_GetPrivateProductCallback cb, + TALER_MERCHANT_GET_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ProductGetHandle *pgh; CURL *eh; - pgh = GNUNET_new (struct TALER_MERCHANT_ProductGetHandle); - pgh->ctx = ctx; - pgh->cb = cb; - pgh->cb_cls = cb_cls; + gpp->cb = cb; + gpp->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/products/%s", - product_id); - pgh->url = TALER_url_join (backend_url, + gpp->product_id); + gpp->url = TALER_url_join (gpp->base_url, path, NULL); GNUNET_free (path); } - if (NULL == pgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (pgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - pgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (pgh->url); - pgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gpp->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpp->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpp->job = GNUNET_CURL_job_add (gpp->ctx, eh, &handle_get_product_finished, - pgh); - return pgh; + gpp); + if (NULL == gpp->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_product_get_cancel ( - struct TALER_MERCHANT_ProductGetHandle *pgh) +TALER_MERCHANT_get_private_product_cancel ( + struct TALER_MERCHANT_GetPrivateProductHandle *gpp) { - if (NULL != pgh->job) - GNUNET_CURL_job_cancel (pgh->job); - GNUNET_free (pgh->url); - GNUNET_free (pgh); + if (NULL != gpp->job) + { + GNUNET_CURL_job_cancel (gpp->job); + gpp->job = NULL; + } + GNUNET_free (gpp->url); + GNUNET_free (gpp->product_id); + GNUNET_free (gpp->base_url); + GNUNET_free (gpp); } + + +/* end of merchant_api_get-private-products-PRODUCT_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-products-new.c b/src/lib/merchant_api_get-private-products-new.c @@ -1,265 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-products-new.c - * @brief Implementation of the GET /private/products request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-products-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of products we return. - */ -#define MAX_PRODUCTS 1024 - - -/** - * Handle for a GET /private/products operation. - */ -struct TALER_MERCHANT_GetPrivateProductsHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateProductsCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse product information from @a ia. - * - * @param ia JSON array (or NULL!) with product data - * @param[in] pgr partially filled response - * @param gpph operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_products (const json_t *ia, - struct TALER_MERCHANT_GetPrivateProductsResponse *pgr, - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph) -{ - unsigned int ies_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) ies_len) || - (ies_len > MAX_PRODUCTS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateProductsInventoryEntry ies[ - GNUNET_NZL (ies_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateProductsInventoryEntry *ie = - &ies[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("product_id", - &ie->product_id), - GNUNET_JSON_spec_uint64 ("product_serial", - &ie->product_serial), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - pgr->details.ok.products_length = ies_len; - pgr->details.ok.products = ies; - gpph->cb (gpph->cb_cls, - pgr); - gpph->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/products request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateProductsHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_products_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateProductsResponse pgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/products response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *products; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("products", - &products), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - pgr.hr.http_status = 0; - pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_products (products, - &pgr, - gpph)) - { - TALER_MERCHANT_get_private_products_cancel (gpph); - return; - } - pgr.hr.http_status = 0; - pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pgr.hr.ec); - break; - } - gpph->cb (gpph->cb_cls, - &pgr); - TALER_MERCHANT_get_private_products_cancel (gpph); -} - - -struct TALER_MERCHANT_GetPrivateProductsHandle * -TALER_MERCHANT_get_private_products_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph; - - gpph = GNUNET_new (struct TALER_MERCHANT_GetPrivateProductsHandle); - gpph->ctx = ctx; - gpph->base_url = GNUNET_strdup (url); - return gpph; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_products_start ( - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph, - TALER_MERCHANT_GetPrivateProductsCallback cb, - TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpph->cb = cb; - gpph->cb_cls = cb_cls; - gpph->url = TALER_url_join (gpph->base_url, - "private/products", - NULL); - if (NULL == gpph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpph->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpph->job = GNUNET_CURL_job_add (gpph->ctx, - eh, - &handle_get_products_finished, - gpph); - if (NULL == gpph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_products_cancel ( - struct TALER_MERCHANT_GetPrivateProductsHandle *gpph) -{ - if (NULL != gpph->job) - { - GNUNET_CURL_job_cancel (gpph->job); - gpph->job = NULL; - } - GNUNET_free (gpph->url); - GNUNET_free (gpph->base_url); - GNUNET_free (gpph); -} - - -/* end of merchant_api_get-private-products-new.c */ diff --git a/src/lib/merchant_api_get-private-products.c b/src/lib/merchant_api_get-private-products.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2024 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-products.c - * @brief Implementation of the GET /products request of the merchant's HTTP API + * @file merchant_api_get-private-products-new.c + * @brief Implementation of the GET /private/products request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,10 +25,9 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-products.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** @@ -38,12 +37,17 @@ /** - * Handle for a GET /products operation. + * Handle for a GET /private/products operation. */ -struct TALER_MERCHANT_ProductsGetHandle +struct TALER_MERCHANT_GetPrivateProductsHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -55,51 +59,50 @@ struct TALER_MERCHANT_ProductsGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductsGetCallback cb; + TALER_MERCHANT_GetPrivateProductsCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Parse product information from @a ia. * - * @param json overall JSON reply * @param ia JSON array (or NULL!) with product data - * @param pgh operation handle + * @param[in] pgr partially filled response + * @param gpph operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue -parse_products (const json_t *json, - const json_t *ia, - struct TALER_MERCHANT_ProductsGetHandle *pgh) +parse_products (const json_t *ia, + struct TALER_MERCHANT_GetPrivateProductsResponse *pgr, + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph) { - unsigned int ies_len = json_array_size (ia); + unsigned int ies_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) ies_len) || + if ( (json_array_size (ia) != (size_t) ies_len) || (ies_len > MAX_PRODUCTS) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_InventoryEntry ies[GNUNET_NZL (ies_len)]; + struct TALER_MERCHANT_GetPrivateProductsInventoryEntry ies[ + GNUNET_NZL (ies_len)]; size_t index; json_t *value; - enum GNUNET_GenericReturnValue ret; - ret = GNUNET_OK; json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_InventoryEntry *ie = &ies[index]; + struct TALER_MERCHANT_GetPrivateProductsInventoryEntry *ie = + &ies[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("product_id", &ie->product_id), @@ -114,35 +117,24 @@ parse_products (const json_t *json, NULL, NULL)) { GNUNET_break_op (0); - ret = GNUNET_SYSERR; - continue; + return GNUNET_SYSERR; } - if (GNUNET_SYSERR == ret) - break; } - if (GNUNET_OK == ret) - { - struct TALER_MERCHANT_GetProductsResponse gpr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details.ok.products_length = ies_len, - .details.ok.products = ies - }; - - pgh->cb (pgh->cb_cls, - &gpr); - pgh->cb = NULL; /* just to be sure */ - } - return ret; + pgr->details.ok.products_length = ies_len; + pgr->details.ok.products = ies; + gpph->cb (gpph->cb_cls, + pgr); + gpph->cb = NULL; } + return GNUNET_OK; } /** * Function called when we're done processing the - * HTTP /products request. + * HTTP GET /private/products request. * - * @param cls the `struct TALER_MERCHANT_ProductsGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateProductsHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -151,16 +143,16 @@ handle_get_products_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_ProductsGetHandle *pgh = cls; + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph = cls; const json_t *json = response; - struct TALER_MERCHANT_GetProductsResponse gpr = { + struct TALER_MERCHANT_GetPrivateProductsResponse pgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - pgh->job = NULL; + gpph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /products response with status code %u\n", + "Got /private/products response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -178,85 +170,96 @@ handle_get_products_finished (void *cls, spec, NULL, NULL)) { - gpr.hr.http_status = 0; - gpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + pgr.hr.http_status = 0; + pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } if (GNUNET_OK == - parse_products (json, - products, - pgh)) + parse_products (products, + &pgr, + gpph)) { - TALER_MERCHANT_products_get_cancel (pgh); + TALER_MERCHANT_get_private_products_cancel (gpph); return; } - gpr.hr.http_status = 0; - gpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + pgr.hr.http_status = 0; + pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - gpr.hr.ec = TALER_JSON_get_error_code (json); - gpr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + pgr.hr.ec = TALER_JSON_get_error_code (json); + pgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - gpr.hr.ec = TALER_JSON_get_error_code (json); - gpr.hr.hint = TALER_JSON_get_error_hint (json); + pgr.hr.ec = TALER_JSON_get_error_code (json); + pgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) gpr.hr.ec); + (int) pgr.hr.ec); break; } - pgh->cb (pgh->cb_cls, - &gpr); - TALER_MERCHANT_products_get_cancel (pgh); + gpph->cb (gpph->cb_cls, + &pgr); + TALER_MERCHANT_get_private_products_cancel (gpph); } -struct TALER_MERCHANT_ProductsGetHandle * -TALER_MERCHANT_products_get ( +struct TALER_MERCHANT_GetPrivateProductsHandle * +TALER_MERCHANT_get_private_products_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_ProductsGetCallback cb, - void *cb_cls) + const char *url) +{ + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph; + + gpph = GNUNET_new (struct TALER_MERCHANT_GetPrivateProductsHandle); + gpph->ctx = ctx; + gpph->base_url = GNUNET_strdup (url); + return gpph; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_products_start ( + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph, + TALER_MERCHANT_GetPrivateProductsCallback cb, + TALER_MERCHANT_GET_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ProductsGetHandle *pgh; CURL *eh; - pgh = GNUNET_new (struct TALER_MERCHANT_ProductsGetHandle); - pgh->ctx = ctx; - pgh->cb = cb; - pgh->cb_cls = cb_cls; - pgh->url = TALER_url_join (backend_url, - "private/products", - NULL); - if (NULL == pgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (pgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - pgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (pgh->url); - pgh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_products_finished, - pgh); - return pgh; + gpph->cb = cb; + gpph->cb_cls = cb_cls; + gpph->url = TALER_url_join (gpph->base_url, + "private/products", + NULL); + if (NULL == gpph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpph->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpph->job = GNUNET_CURL_job_add (gpph->ctx, + eh, + &handle_get_products_finished, + gpph); + if (NULL == gpph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_products_get_cancel ( - struct TALER_MERCHANT_ProductsGetHandle *pgh) +TALER_MERCHANT_get_private_products_cancel ( + struct TALER_MERCHANT_GetPrivateProductsHandle *gpph) { - if (NULL != pgh->job) - GNUNET_CURL_job_cancel (pgh->job); - GNUNET_free (pgh->url); - GNUNET_free (pgh); + if (NULL != gpph->job) + { + GNUNET_CURL_job_cancel (gpph->job); + gpph->job = NULL; + } + GNUNET_free (gpph->url); + GNUNET_free (gpph->base_url); + GNUNET_free (gpph); } + + +/* end of merchant_api_get-private-products-new.c */ diff --git a/src/lib/merchant_api_get-private-statistics-amount-SLUG-new.c b/src/lib/merchant_api_get-private-statistics-amount-SLUG-new.c @@ -1,455 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-statistics-amount-SLUG-new.c - * @brief Implementation of the GET /private/statistics-amount/$SLUG request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-statistics-amount-SLUG-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of statistics entries we return. - */ -#define MAX_STATISTICS 1024 - - -/** - * Handle for a GET /private/statistics-amount/$SLUG operation. - */ -struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateStatisticsAmountCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Statistics slug. - */ - char *slug; - - /** - * Aggregation mode. - */ - enum TALER_MERCHANT_StatisticsType stype; - - /** - * Whether stype was explicitly set. - */ - bool have_stype; -}; - - -/** - * Parse interval and bucket data from the JSON response. - * - * @param json overall JSON reply - * @param jbuckets JSON array with bucket data - * @param buckets_description human-readable description for buckets - * @param jintervals JSON array with interval data - * @param intervals_description human-readable description for intervals - * @param sah operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_intervals_and_buckets_amt ( - const json_t *json, - const json_t *jbuckets, - const char *buckets_description, - const json_t *jintervals, - const char *intervals_description, - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah) -{ - unsigned int resp_buckets_len = json_array_size (jbuckets); - unsigned int resp_intervals_len = json_array_size (jintervals); - - if ( (json_array_size (jbuckets) != (size_t) resp_buckets_len) || - (json_array_size (jintervals) != (size_t) resp_intervals_len) || - (resp_buckets_len > MAX_STATISTICS) || - (resp_intervals_len > MAX_STATISTICS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket resp_buckets[ - GNUNET_NZL (resp_buckets_len)]; - struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval resp_intervals[ - GNUNET_NZL (resp_intervals_len)]; - size_t index; - json_t *value; - enum GNUNET_GenericReturnValue ret; - - ret = GNUNET_OK; - json_array_foreach (jintervals, index, value) { - struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval *jinterval - = &resp_intervals[index]; - const json_t *amounts_arr; - size_t amounts_len; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_timestamp ("start_time", - &jinterval->start_time), - GNUNET_JSON_spec_array_const ("cumulative_amounts", - &amounts_arr), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - amounts_len = json_array_size (amounts_arr); - { - struct TALER_Amount amt_arr[GNUNET_NZL (amounts_len)]; - size_t aindex; - json_t *avalue; - - jinterval->cumulative_amount_len = amounts_len; - jinterval->cumulative_amounts = amt_arr; - json_array_foreach (amounts_arr, aindex, avalue) { - if (! json_is_string (avalue)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_string_to_amount (json_string_value (avalue), - &amt_arr[aindex])) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - } - } - json_array_foreach (jbuckets, index, value) { - struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket *jbucket - = &resp_buckets[index]; - const json_t *amounts_arr; - size_t amounts_len; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_timestamp ("start_time", - &jbucket->start_time), - GNUNET_JSON_spec_timestamp ("end_time", - &jbucket->end_time), - GNUNET_JSON_spec_string ("range", - &jbucket->range), - GNUNET_JSON_spec_array_const ("cumulative_amounts", - &amounts_arr), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - ret = GNUNET_SYSERR; - break; - } - amounts_len = json_array_size (amounts_arr); - { - struct TALER_Amount amt_arr[GNUNET_NZL (amounts_len)]; - size_t aindex; - json_t *avalue; - - jbucket->cumulative_amount_len = amounts_len; - jbucket->cumulative_amounts = amt_arr; - json_array_foreach (amounts_arr, aindex, avalue) { - if (! json_is_string (avalue)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_string_to_amount (json_string_value (avalue), - &amt_arr[aindex])) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - } - } - if (GNUNET_OK == ret) - { - struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse sagr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details.ok.buckets_length = resp_buckets_len, - .details.ok.buckets = resp_buckets, - .details.ok.buckets_description = buckets_description, - .details.ok.intervals_length = resp_intervals_len, - .details.ok.intervals = resp_intervals, - .details.ok.intervals_description = intervals_description, - }; - sah->cb (sah->cb_cls, - &sagr); - sah->cb = NULL; - } - return ret; - } -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/statistics-amount/$SLUG request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_statistics_amount_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse sagr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - sah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/statistics-amount/$SLUG response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *buckets; - const json_t *intervals; - const char *buckets_description = NULL; - const char *intervals_description = NULL; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("buckets", - &buckets), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("buckets_description", - &buckets_description), - NULL), - GNUNET_JSON_spec_array_const ("intervals", - &intervals), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("intervals_description", - &intervals_description), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - sagr.hr.http_status = 0; - sagr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_intervals_and_buckets_amt (json, - buckets, - buckets_description, - intervals, - intervals_description, - sah)) - { - TALER_MERCHANT_get_private_statistics_amount_cancel (sah); - return; - } - sagr.hr.http_status = 0; - sagr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - sagr.hr.ec = TALER_JSON_get_error_code (json); - sagr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - sagr.hr.ec = TALER_JSON_get_error_code (json); - sagr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - sagr.hr.ec = TALER_JSON_get_error_code (json); - sagr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) sagr.hr.ec); - break; - } - sah->cb (sah->cb_cls, - &sagr); - TALER_MERCHANT_get_private_statistics_amount_cancel (sah); -} - - -struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle * -TALER_MERCHANT_get_private_statistics_amount_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *slug) -{ - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah; - - sah = GNUNET_new (struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle); - sah->ctx = ctx; - sah->base_url = GNUNET_strdup (url); - sah->slug = GNUNET_strdup (slug); - sah->stype = TALER_MERCHANT_STATISTICS_ALL; - return sah; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_private_statistics_amount_set_options_ ( - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue *opt = - &options[i]; - - switch (opt->option) - { - case TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE: - sah->stype = opt->details.type; - sah->have_stype = true; - break; - default: - GNUNET_break (0); - return GNUNET_NO; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_statistics_amount_start ( - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, - TALER_MERCHANT_GetPrivateStatisticsAmountCallback cb, - TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - sah->cb = cb; - sah->cb_cls = cb_cls; - { - const char *filter = NULL; - char *path; - - switch (sah->stype) - { - case TALER_MERCHANT_STATISTICS_BY_BUCKET: - filter = "bucket"; - break; - case TALER_MERCHANT_STATISTICS_BY_INTERVAL: - filter = "interval"; - break; - case TALER_MERCHANT_STATISTICS_ALL: - filter = NULL; - break; - } - GNUNET_asprintf (&path, - "private/statistics-amount/%s", - sah->slug); - sah->url = TALER_url_join (sah->base_url, - path, - "by", - filter, - NULL); - GNUNET_free (path); - } - if (NULL == sah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (sah->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - sah->job = GNUNET_CURL_job_add (sah->ctx, - eh, - &handle_get_statistics_amount_finished, - sah); - if (NULL == sah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_statistics_amount_cancel ( - struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah) -{ - if (NULL != sah->job) - { - GNUNET_CURL_job_cancel (sah->job); - sah->job = NULL; - } - GNUNET_free (sah->url); - GNUNET_free (sah->base_url); - GNUNET_free (sah->slug); - GNUNET_free (sah); -} - - -/* end of merchant_api_get-private-statistics-amount-SLUG-new.c */ diff --git a/src/lib/merchant_api_get-private-statistics-amount-SLUG.c b/src/lib/merchant_api_get-private-statistics-amount-SLUG.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,35 +15,39 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-statistics-amount-SLUG.c - * @brief Implementation of the GET /private/statistics-amount/$SLUG request of the merchant's HTTP API - * @author Martin Schanzenbach + * @file merchant_api_get-private-statistics-amount-SLUG-new.c + * @brief Implementation of the GET /private/statistics-amount/$SLUG request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> -#include <gnunet/gnunet_common.h> -#include <gnunet/gnunet_json_lib.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-statistics-amount-SLUG.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> + /** - * Maximum number of statistics we return + * Maximum number of statistics entries we return. */ #define MAX_STATISTICS 1024 + /** - * Handle for a GET /statistics-amount/$SLUG operation. + * Handle for a GET /private/statistics-amount/$SLUG operation. */ -struct TALER_MERCHANT_StatisticsAmountGetHandle +struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -55,30 +59,44 @@ struct TALER_MERCHANT_StatisticsAmountGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_StatisticsAmountGetCallback cb; + TALER_MERCHANT_GetPrivateStatisticsAmountCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Statistics slug. + */ + char *slug; + + /** + * Aggregation mode. + */ + enum TALER_MERCHANT_StatisticsType stype; + + /** + * Whether stype was explicitly set. + */ + bool have_stype; }; /** - * Parse interval information from buckets and intervals. + * Parse interval and bucket data from the JSON response. * * @param json overall JSON reply - * @param jbuckets JSON array (or NULL!) with bucket data - * @param buckets_description human-readable description for the buckets - * @param jintervals JSON array (or NULL!) with bucket data - * @param intervals_description human-readable description for the intervals - * @param sgh operation handle + * @param jbuckets JSON array with bucket data + * @param buckets_description human-readable description for buckets + * @param jintervals JSON array with interval data + * @param intervals_description human-readable description for intervals + * @param sah operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue @@ -88,23 +106,23 @@ parse_intervals_and_buckets_amt ( const char *buckets_description, const json_t *jintervals, const char *intervals_description, - struct TALER_MERCHANT_StatisticsAmountGetHandle *sgh - ) + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah) { unsigned int resp_buckets_len = json_array_size (jbuckets); unsigned int resp_intervals_len = json_array_size (jintervals); - if ( (json_array_size (jbuckets) != (size_t) resp_buckets_len) || - (json_array_size (jintervals) != (size_t) resp_intervals_len) || - (resp_intervals_len = resp_buckets_len > MAX_STATISTICS) ) + if ( (json_array_size (jbuckets) != (size_t) resp_buckets_len) || + (json_array_size (jintervals) != (size_t) resp_intervals_len) || + (resp_buckets_len > MAX_STATISTICS) || + (resp_intervals_len > MAX_STATISTICS) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_StatisticAmountByBucket resp_buckets[ + struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket resp_buckets[ GNUNET_NZL (resp_buckets_len)]; - struct TALER_MERCHANT_StatisticAmountByInterval resp_intervals[ + struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval resp_intervals[ GNUNET_NZL (resp_intervals_len)]; size_t index; json_t *value; @@ -112,11 +130,10 @@ parse_intervals_and_buckets_amt ( ret = GNUNET_OK; json_array_foreach (jintervals, index, value) { - struct TALER_MERCHANT_StatisticAmountByInterval *jinterval + struct TALER_MERCHANT_GetPrivateStatisticsAmountByInterval *jinterval = &resp_intervals[index]; const json_t *amounts_arr; size_t amounts_len; - struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ("start_time", &jinterval->start_time), @@ -131,14 +148,11 @@ parse_intervals_and_buckets_amt ( NULL, NULL)) { GNUNET_break_op (0); - ret = GNUNET_SYSERR; - continue; + return GNUNET_SYSERR; } - if (GNUNET_SYSERR == ret) - break; amounts_len = json_array_size (amounts_arr); { - struct TALER_Amount amt_arr[amounts_len]; + struct TALER_Amount amt_arr[GNUNET_NZL (amounts_len)]; size_t aindex; json_t *avalue; @@ -160,9 +174,8 @@ parse_intervals_and_buckets_amt ( } } } - ret = GNUNET_OK; json_array_foreach (jbuckets, index, value) { - struct TALER_MERCHANT_StatisticAmountByBucket *jbucket + struct TALER_MERCHANT_GetPrivateStatisticsAmountByBucket *jbucket = &resp_buckets[index]; const json_t *amounts_arr; size_t amounts_len; @@ -185,21 +198,14 @@ parse_intervals_and_buckets_amt ( { GNUNET_break_op (0); ret = GNUNET_SYSERR; - continue; - } - if (GNUNET_SYSERR == ret) - break; - amounts_len = json_array_size (amounts_arr); - if (0 > amounts_len) - { - GNUNET_break_op (0); - ret = GNUNET_SYSERR; break; } + amounts_len = json_array_size (amounts_arr); { - struct TALER_Amount amt_arr[amounts_len]; + struct TALER_Amount amt_arr[GNUNET_NZL (amounts_len)]; size_t aindex; json_t *avalue; + jbucket->cumulative_amount_len = amounts_len; jbucket->cumulative_amounts = amt_arr; json_array_foreach (amounts_arr, aindex, avalue) { @@ -220,7 +226,7 @@ parse_intervals_and_buckets_amt ( } if (GNUNET_OK == ret) { - struct TALER_MERCHANT_StatisticsAmountGetResponse gsr = { + struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse sagr = { .hr.http_status = MHD_HTTP_OK, .hr.reply = json, .details.ok.buckets_length = resp_buckets_len, @@ -230,9 +236,9 @@ parse_intervals_and_buckets_amt ( .details.ok.intervals = resp_intervals, .details.ok.intervals_description = intervals_description, }; - sgh->cb (sgh->cb_cls, - &gsr); - sgh->cb = NULL; /* just to be sure */ + sah->cb (sah->cb_cls, + &sagr); + sah->cb = NULL; } return ret; } @@ -241,9 +247,9 @@ parse_intervals_and_buckets_amt ( /** * Function called when we're done processing the - * HTTP GET /statistics-amount/$SLUG request. + * HTTP GET /private/statistics-amount/$SLUG request. * - * @param cls the `struct TALER_MERCHANT_StatisticsAmountGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -252,16 +258,16 @@ handle_get_statistics_amount_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_StatisticsAmountGetHandle *handle = cls; + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah = cls; const json_t *json = response; - struct TALER_MERCHANT_StatisticsAmountGetResponse res = { + struct TALER_MERCHANT_GetPrivateStatisticsAmountResponse sagr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - handle->job = NULL; + sah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /statistics-amount/$SLUG response with status code %u\n", + "Got /private/statistics-amount/$SLUG response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -292,8 +298,8 @@ handle_get_statistics_amount_finished (void *cls, spec, NULL, NULL)) { - res.hr.http_status = 0; - res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + sagr.hr.http_status = 0; + sagr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } if (GNUNET_OK == @@ -302,58 +308,98 @@ handle_get_statistics_amount_finished (void *cls, buckets_description, intervals, intervals_description, - handle)) + sah)) { - TALER_MERCHANT_statistic_amount_get_cancel (handle); + TALER_MERCHANT_get_private_statistics_amount_cancel (sah); return; } - res.hr.http_status = 0; - res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + sagr.hr.http_status = 0; + sagr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + sagr.hr.ec = TALER_JSON_get_error_code (json); + sagr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); + sagr.hr.ec = TALER_JSON_get_error_code (json); + sagr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); + sagr.hr.ec = TALER_JSON_get_error_code (json); + sagr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) res.hr.ec); + (int) sagr.hr.ec); break; } + sah->cb (sah->cb_cls, + &sagr); + TALER_MERCHANT_get_private_statistics_amount_cancel (sah); } -struct TALER_MERCHANT_StatisticsAmountGetHandle * -TALER_MERCHANT_statistic_amount_get ( +struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle * +TALER_MERCHANT_get_private_statistics_amount_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *slug, - enum TALER_MERCHANT_StatisticsType stype, - TALER_MERCHANT_StatisticsAmountGetCallback cb, - void *cb_cls) + const char *url, + const char *slug) +{ + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah; + + sah = GNUNET_new (struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle); + sah->ctx = ctx; + sah->base_url = GNUNET_strdup (url); + sah->slug = GNUNET_strdup (slug); + sah->stype = TALER_MERCHANT_STATISTICS_ALL; + return sah; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_statistics_amount_set_options_ ( + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_MERCHANT_GetPrivateStatisticsAmountOptionValue *opt = + &options[i]; + + switch (opt->option) + { + case TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_OPTION_TYPE: + sah->stype = opt->details.type; + sah->have_stype = true; + break; + default: + GNUNET_break (0); + return GNUNET_NO; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_statistics_amount_start ( + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah, + TALER_MERCHANT_GetPrivateStatisticsAmountCallback cb, + TALER_MERCHANT_GET_PRIVATE_STATISTICS_AMOUNT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_StatisticsAmountGetHandle *handle; CURL *eh; - handle = GNUNET_new (struct TALER_MERCHANT_StatisticsAmountGetHandle); - handle->ctx = ctx; - handle->cb = cb; - handle->cb_cls = cb_cls; + sah->cb = cb; + sah->cb_cls = cb_cls; { const char *filter = NULL; char *path; - switch (stype) + switch (sah->stype) { case TALER_MERCHANT_STATISTICS_BY_BUCKET: filter = "bucket"; @@ -367,42 +413,43 @@ TALER_MERCHANT_statistic_amount_get ( } GNUNET_asprintf (&path, "private/statistics-amount/%s", - slug); - handle->url = TALER_url_join (backend_url, - path, - "by", - filter, - NULL); + sah->slug); + sah->url = TALER_url_join (sah->base_url, + path, + "by", + filter, + NULL); GNUNET_free (path); } - if (NULL == handle->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (handle); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - handle->url); - eh = TALER_MERCHANT_curl_easy_get_ (handle->url); - handle->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_statistics_amount_finished, - handle); - return handle; + if (NULL == sah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (sah->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + sah->job = GNUNET_CURL_job_add (sah->ctx, + eh, + &handle_get_statistics_amount_finished, + sah); + if (NULL == sah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_statistic_amount_get_cancel ( - struct TALER_MERCHANT_StatisticsAmountGetHandle *handle) +TALER_MERCHANT_get_private_statistics_amount_cancel ( + struct TALER_MERCHANT_GetPrivateStatisticsAmountHandle *sah) { - if (NULL != handle->job) - GNUNET_CURL_job_cancel (handle->job); - GNUNET_free (handle->url); - GNUNET_free (handle); + if (NULL != sah->job) + { + GNUNET_CURL_job_cancel (sah->job); + sah->job = NULL; + } + GNUNET_free (sah->url); + GNUNET_free (sah->base_url); + GNUNET_free (sah->slug); + GNUNET_free (sah); } -/* end of merchant_api_get-private-statistics-amount-SLUG.c */ +/* end of merchant_api_get-private-statistics-amount-SLUG-new.c */ diff --git a/src/lib/merchant_api_get-private-statistics-counter-SLUG-new.c b/src/lib/merchant_api_get-private-statistics-counter-SLUG-new.c @@ -1,400 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-statistics-counter-SLUG-new.c - * @brief Implementation of the GET /private/statistics-counter/$SLUG request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-statistics-counter-SLUG-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - -/** - * Maximum number of statistics we return. - */ -#define MAX_STATISTICS 1024 - - -/** - * Handle for a GET /private/statistics-counter/$SLUG operation. - */ -struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateStatisticsCounterCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Statistics slug to retrieve. - */ - char *slug; - - /** - * Aggregation filter type, or -1 if not set. - */ - enum TALER_MERCHANT_StatisticsType stype; - - /** - * Whether the type option was set. - */ - bool type_set; -}; - - -/** - * Parse interval and bucket information from the JSON response. - * - * @param json overall JSON reply - * @param jbuckets JSON array with bucket data - * @param buckets_description human-readable description for the buckets - * @param jintervals JSON array with interval data - * @param intervals_description human-readable description for the intervals - * @param sch operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_intervals_and_buckets ( - const json_t *json, - const json_t *jbuckets, - const char *buckets_description, - const json_t *jintervals, - const char *intervals_description, - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch) -{ - unsigned int resp_buckets_len = (unsigned int) json_array_size (jbuckets); - unsigned int resp_intervals_len = (unsigned int) json_array_size (jintervals); - - if ( (json_array_size (jbuckets) != (size_t) resp_buckets_len) || - (json_array_size (jintervals) != (size_t) resp_intervals_len) || - (resp_buckets_len > MAX_STATISTICS) || - (resp_intervals_len > MAX_STATISTICS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket resp_buckets[ - GNUNET_NZL (resp_buckets_len)]; - struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval resp_intervals[ - GNUNET_NZL (resp_intervals_len)]; - size_t index; - json_t *value; - - json_array_foreach (jintervals, index, value) { - struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval *ji - = &resp_intervals[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_timestamp ("start_time", - &ji->start_time), - GNUNET_JSON_spec_uint64 ("cumulative_counter", - &ji->cumulative_counter), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - json_array_foreach (jbuckets, index, value) { - struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket *jb - = &resp_buckets[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_timestamp ("start_time", - &jb->start_time), - GNUNET_JSON_spec_timestamp ("end_time", - &jb->end_time), - GNUNET_JSON_spec_string ("range", - &jb->range), - GNUNET_JSON_spec_uint64 ("cumulative_counter", - &jb->cumulative_counter), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - { - struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse scgr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details.ok.buckets_length = resp_buckets_len, - .details.ok.buckets = resp_buckets, - .details.ok.buckets_description = buckets_description, - .details.ok.intervals_length = resp_intervals_len, - .details.ok.intervals = resp_intervals, - .details.ok.intervals_description = intervals_description, - }; - sch->cb (sch->cb_cls, - &scgr); - sch->cb = NULL; - } - return GNUNET_OK; - } -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/statistics-counter/$SLUG request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_statistics_counter_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse res = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - sch->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/statistics-counter/$SLUG response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *buckets; - const json_t *intervals; - const char *buckets_description = NULL; - const char *intervals_description = NULL; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("buckets", - &buckets), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("buckets_description", - &buckets_description), - NULL), - GNUNET_JSON_spec_array_const ("intervals", - &intervals), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("intervals_description", - &intervals_description), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - res.hr.http_status = 0; - res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_intervals_and_buckets (json, - buckets, - buckets_description, - intervals, - intervals_description, - sch)) - { - TALER_MERCHANT_get_private_statistics_counter_cancel (sch); - return; - } - res.hr.http_status = 0; - res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) res.hr.ec); - break; - } - sch->cb (sch->cb_cls, - &res); - TALER_MERCHANT_get_private_statistics_counter_cancel (sch); -} - - -struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle * -TALER_MERCHANT_get_private_statistics_counter_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *slug) -{ - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch; - - sch = GNUNET_new (struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle); - sch->ctx = ctx; - sch->base_url = GNUNET_strdup (url); - sch->slug = GNUNET_strdup (slug); - sch->type_set = false; - return sch; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_private_statistics_counter_set_options_ ( - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE: - sch->stype = options[i].details.type; - sch->type_set = true; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_statistics_counter_start ( - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, - TALER_MERCHANT_GetPrivateStatisticsCounterCallback cb, - TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - sch->cb = cb; - sch->cb_cls = cb_cls; - { - const char *filter = NULL; - char *path; - - if (sch->type_set) - { - switch (sch->stype) - { - case TALER_MERCHANT_STATISTICS_BY_BUCKET: - filter = "bucket"; - break; - case TALER_MERCHANT_STATISTICS_BY_INTERVAL: - filter = "interval"; - break; - case TALER_MERCHANT_STATISTICS_ALL: - filter = NULL; - break; - } - } - GNUNET_asprintf (&path, - "private/statistics-counter/%s", - sch->slug); - sch->url = TALER_url_join (sch->base_url, - path, - "by", - filter, - NULL); - GNUNET_free (path); - } - if (NULL == sch->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (sch->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - sch->job = GNUNET_CURL_job_add (sch->ctx, - eh, - &handle_get_statistics_counter_finished, - sch); - if (NULL == sch->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_statistics_counter_cancel ( - struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch) -{ - if (NULL != sch->job) - { - GNUNET_CURL_job_cancel (sch->job); - sch->job = NULL; - } - GNUNET_free (sch->slug); - GNUNET_free (sch->url); - GNUNET_free (sch->base_url); - GNUNET_free (sch); -} - - -/* end of merchant_api_get-private-statistics-counter-SLUG-new.c */ diff --git a/src/lib/merchant_api_get-private-statistics-counter-SLUG.c b/src/lib/merchant_api_get-private-statistics-counter-SLUG.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,35 +15,38 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-statistics-counter-SLUG.c - * @brief Implementation of the GET /private/statistics-counter/$SLUG request of the merchant's HTTP API - * @author Martin Schanzenbach + * @file merchant_api_get-private-statistics-counter-SLUG-new.c + * @brief Implementation of the GET /private/statistics-counter/$SLUG request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> -#include <gnunet/gnunet_common.h> -#include <gnunet/gnunet_json_lib.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-statistics-counter-SLUG.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Maximum number of statistics we return + * Maximum number of statistics we return. */ #define MAX_STATISTICS 1024 + /** - * Handle for a GET /statistics-counter/$SLUG operation. + * Handle for a GET /private/statistics-counter/$SLUG operation. */ -struct TALER_MERCHANT_StatisticsCounterGetHandle +struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -55,30 +58,44 @@ struct TALER_MERCHANT_StatisticsCounterGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_StatisticsCounterGetCallback cb; + TALER_MERCHANT_GetPrivateStatisticsCounterCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Statistics slug to retrieve. + */ + char *slug; + + /** + * Aggregation filter type, or -1 if not set. + */ + enum TALER_MERCHANT_StatisticsType stype; + + /** + * Whether the type option was set. + */ + bool type_set; }; /** - * Parse interval information from @a ia. + * Parse interval and bucket information from the JSON response. * * @param json overall JSON reply - * @param jbuckets JSON array (or NULL!) with bucket data + * @param jbuckets JSON array with bucket data * @param buckets_description human-readable description for the buckets - * @param jintervals JSON array (or NULL!) with bucket data + * @param jintervals JSON array with interval data * @param intervals_description human-readable description for the intervals - * @param scgh operation handle + * @param sch operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue @@ -88,36 +105,35 @@ parse_intervals_and_buckets ( const char *buckets_description, const json_t *jintervals, const char *intervals_description, - struct TALER_MERCHANT_StatisticsCounterGetHandle *scgh) + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch) { - unsigned int resp_buckets_len = json_array_size (jbuckets); - unsigned int resp_intervals_len = json_array_size (jintervals); + unsigned int resp_buckets_len = (unsigned int) json_array_size (jbuckets); + unsigned int resp_intervals_len = (unsigned int) json_array_size (jintervals); - if ( (json_array_size (jbuckets) != (size_t) resp_buckets_len) || - (json_array_size (jintervals) != (size_t) resp_intervals_len) || - (resp_intervals_len = resp_buckets_len > MAX_STATISTICS) ) + if ( (json_array_size (jbuckets) != (size_t) resp_buckets_len) || + (json_array_size (jintervals) != (size_t) resp_intervals_len) || + (resp_buckets_len > MAX_STATISTICS) || + (resp_intervals_len > MAX_STATISTICS) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_StatisticCounterByBucket resp_buckets[ + struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket resp_buckets[ GNUNET_NZL (resp_buckets_len)]; - struct TALER_MERCHANT_StatisticCounterByInterval resp_intervals[ + struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval resp_intervals[ GNUNET_NZL (resp_intervals_len)]; size_t index; json_t *value; - enum GNUNET_GenericReturnValue ret; - ret = GNUNET_OK; json_array_foreach (jintervals, index, value) { - struct TALER_MERCHANT_StatisticCounterByInterval *jinterval + struct TALER_MERCHANT_GetPrivateStatisticsCounterByInterval *ji = &resp_intervals[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ("start_time", - &jinterval->start_time), + &ji->start_time), GNUNET_JSON_spec_uint64 ("cumulative_counter", - &jinterval->cumulative_counter), + &ji->cumulative_counter), GNUNET_JSON_spec_end () }; @@ -127,25 +143,21 @@ parse_intervals_and_buckets ( NULL, NULL)) { GNUNET_break_op (0); - ret = GNUNET_SYSERR; - continue; + return GNUNET_SYSERR; } - if (GNUNET_SYSERR == ret) - break; } - ret = GNUNET_OK; json_array_foreach (jbuckets, index, value) { - struct TALER_MERCHANT_StatisticCounterByBucket *jbucket = &resp_buckets[ - index]; + struct TALER_MERCHANT_GetPrivateStatisticsCounterByBucket *jb + = &resp_buckets[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_timestamp ("start_time", - &jbucket->start_time), + &jb->start_time), GNUNET_JSON_spec_timestamp ("end_time", - &jbucket->end_time), + &jb->end_time), GNUNET_JSON_spec_string ("range", - &jbucket->range), + &jb->range), GNUNET_JSON_spec_uint64 ("cumulative_counter", - &jbucket->cumulative_counter), + &jb->cumulative_counter), GNUNET_JSON_spec_end () }; @@ -155,15 +167,11 @@ parse_intervals_and_buckets ( NULL, NULL)) { GNUNET_break_op (0); - ret = GNUNET_SYSERR; - continue; + return GNUNET_SYSERR; } - if (GNUNET_SYSERR == ret) - break; } - if (GNUNET_OK == ret) { - struct TALER_MERCHANT_StatisticsCounterGetResponse gsr = { + struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse scgr = { .hr.http_status = MHD_HTTP_OK, .hr.reply = json, .details.ok.buckets_length = resp_buckets_len, @@ -173,20 +181,20 @@ parse_intervals_and_buckets ( .details.ok.intervals = resp_intervals, .details.ok.intervals_description = intervals_description, }; - scgh->cb (scgh->cb_cls, - &gsr); - scgh->cb = NULL; /* just to be sure */ + sch->cb (sch->cb_cls, + &scgr); + sch->cb = NULL; } - return ret; + return GNUNET_OK; } } /** * Function called when we're done processing the - * HTTP GET /statistics-counter/$SLUG request. + * HTTP GET /private/statistics-counter/$SLUG request. * - * @param cls the `struct TALER_MERCHANT_StatisticsCounterGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -195,16 +203,16 @@ handle_get_statistics_counter_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_StatisticsCounterGetHandle *handle = cls; + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch = cls; const json_t *json = response; - struct TALER_MERCHANT_StatisticsCounterGetResponse res = { + struct TALER_MERCHANT_GetPrivateStatisticsCounterResponse res = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - handle->job = NULL; + sch->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /statistics-counter/$SLUG response with status code %u\n", + "Got /private/statistics-counter/$SLUG response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -212,8 +220,8 @@ handle_get_statistics_counter_finished (void *cls, { const json_t *buckets; const json_t *intervals; - const char *buckets_description; - const char *intervals_description; + const char *buckets_description = NULL; + const char *intervals_description = NULL; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_array_const ("buckets", &buckets), @@ -239,17 +247,15 @@ handle_get_statistics_counter_finished (void *cls, res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "%s\n", json_dumps (json, JSON_INDENT (1))); if (GNUNET_OK == parse_intervals_and_buckets (json, buckets, buckets_description, intervals, intervals_description, - handle)) + sch)) { - TALER_MERCHANT_statistic_counter_get_cancel (handle); + TALER_MERCHANT_get_private_statistics_counter_cancel (sch); return; } res.hr.http_status = 0; @@ -259,14 +265,12 @@ handle_get_statistics_counter_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: res.hr.ec = TALER_JSON_get_error_code (json); res.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: res.hr.ec = TALER_JSON_get_error_code (json); res.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ res.hr.ec = TALER_JSON_get_error_code (json); res.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -275,79 +279,122 @@ handle_get_statistics_counter_finished (void *cls, (int) res.hr.ec); break; } + sch->cb (sch->cb_cls, + &res); + TALER_MERCHANT_get_private_statistics_counter_cancel (sch); } -struct TALER_MERCHANT_StatisticsCounterGetHandle * -TALER_MERCHANT_statistic_counter_get ( +struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle * +TALER_MERCHANT_get_private_statistics_counter_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *slug, - enum TALER_MERCHANT_StatisticsType stype, - TALER_MERCHANT_StatisticsCounterGetCallback cb, - void *cb_cls) + const char *url, + const char *slug) +{ + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch; + + sch = GNUNET_new (struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle); + sch->ctx = ctx; + sch->base_url = GNUNET_strdup (url); + sch->slug = GNUNET_strdup (slug); + sch->type_set = false; + return sch; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_statistics_counter_set_options_ ( + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateStatisticsCounterOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_OPTION_TYPE: + sch->stype = options[i].details.type; + sch->type_set = true; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_statistics_counter_start ( + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch, + TALER_MERCHANT_GetPrivateStatisticsCounterCallback cb, + TALER_MERCHANT_GET_PRIVATE_STATISTICS_COUNTER_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_StatisticsCounterGetHandle *handle; CURL *eh; - handle = GNUNET_new (struct TALER_MERCHANT_StatisticsCounterGetHandle); - handle->ctx = ctx; - handle->cb = cb; - handle->cb_cls = cb_cls; + sch->cb = cb; + sch->cb_cls = cb_cls; { const char *filter = NULL; char *path; - switch (stype) + if (sch->type_set) { - case TALER_MERCHANT_STATISTICS_BY_BUCKET: - filter = "bucket"; - break; - case TALER_MERCHANT_STATISTICS_BY_INTERVAL: - filter = "interval"; - break; - case TALER_MERCHANT_STATISTICS_ALL: - filter = NULL; - break; + switch (sch->stype) + { + case TALER_MERCHANT_STATISTICS_BY_BUCKET: + filter = "bucket"; + break; + case TALER_MERCHANT_STATISTICS_BY_INTERVAL: + filter = "interval"; + break; + case TALER_MERCHANT_STATISTICS_ALL: + filter = NULL; + break; + } } GNUNET_asprintf (&path, "private/statistics-counter/%s", - slug); - handle->url = TALER_url_join (backend_url, - path, - "by", - filter, - NULL); + sch->slug); + sch->url = TALER_url_join (sch->base_url, + path, + "by", + filter, + NULL); GNUNET_free (path); } - if (NULL == handle->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (handle); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - handle->url); - eh = TALER_MERCHANT_curl_easy_get_ (handle->url); - handle->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_statistics_counter_finished, - handle); - return handle; + if (NULL == sch->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (sch->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + sch->job = GNUNET_CURL_job_add (sch->ctx, + eh, + &handle_get_statistics_counter_finished, + sch); + if (NULL == sch->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_statistic_counter_get_cancel ( - struct TALER_MERCHANT_StatisticsCounterGetHandle *handle) +TALER_MERCHANT_get_private_statistics_counter_cancel ( + struct TALER_MERCHANT_GetPrivateStatisticsCounterHandle *sch) { - if (NULL != handle->job) - GNUNET_CURL_job_cancel (handle->job); - GNUNET_free (handle->url); - GNUNET_free (handle); + if (NULL != sch->job) + { + GNUNET_CURL_job_cancel (sch->job); + sch->job = NULL; + } + GNUNET_free (sch->slug); + GNUNET_free (sch->url); + GNUNET_free (sch->base_url); + GNUNET_free (sch); } -/* end of merchant_api_get-private-statistics-counter-SLUG.c */ +/* end of merchant_api_get-private-statistics-counter-SLUG-new.c */ diff --git a/src/lib/merchant_api_get-private-templates-TEMPLATE_ID-new.c b/src/lib/merchant_api_get-private-templates-TEMPLATE_ID-new.c @@ -1,222 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-templates-TEMPLATE_ID-new.c - * @brief Implementation of the GET /private/templates/$TEMPLATE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/templates/$TEMPLATE_ID operation. - */ -struct TALER_MERCHANT_GetPrivateTemplateHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * Template identifier. - */ - char *template_id; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateTemplateCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /private/templates/$TEMPLATE_ID request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateTemplateHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_template_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateTemplateResponse tgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpt->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/templates/$TEMPLATE_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *contract; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("template_description", - &tgr.details.ok.template_description), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("otp_id", - &tgr.details.ok.otp_id), - NULL), - GNUNET_JSON_spec_object_const ("template_contract", - &contract), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - tgr.details.ok.template_contract = contract; - gpt->cb (gpt->cb_cls, - &tgr); - TALER_MERCHANT_get_private_template_cancel (gpt); - return; - } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) tgr.hr.ec); - break; - } - gpt->cb (gpt->cb_cls, - &tgr); - TALER_MERCHANT_get_private_template_cancel (gpt); -} - - -struct TALER_MERCHANT_GetPrivateTemplateHandle * -TALER_MERCHANT_get_private_template_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id) -{ - struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt; - - gpt = GNUNET_new (struct TALER_MERCHANT_GetPrivateTemplateHandle); - gpt->ctx = ctx; - gpt->base_url = GNUNET_strdup (url); - gpt->template_id = GNUNET_strdup (template_id); - return gpt; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_template_start ( - struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt, - TALER_MERCHANT_GetPrivateTemplateCallback cb, - TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpt->cb = cb; - gpt->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/templates/%s", - gpt->template_id); - gpt->url = TALER_url_join (gpt->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gpt->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpt->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpt->job = GNUNET_CURL_job_add (gpt->ctx, - eh, - &handle_get_template_finished, - gpt); - if (NULL == gpt->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_template_cancel ( - struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt) -{ - if (NULL != gpt->job) - { - GNUNET_CURL_job_cancel (gpt->job); - gpt->job = NULL; - } - GNUNET_free (gpt->url); - GNUNET_free (gpt->template_id); - GNUNET_free (gpt->base_url); - GNUNET_free (gpt); -} - - -/* end of merchant_api_get-private-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-templates-TEMPLATE_ID.c b/src/lib/merchant_api_get-private-templates-TEMPLATE_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-templates-TEMPLATE_ID.c - * @brief Implementation of the GET /templates/$ID request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_get-private-templates-TEMPLATE_ID-new.c + * @brief Implementation of the GET /private/templates/$TEMPLATE_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +25,28 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-templates-TEMPLATE_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /templates/$ID operation. + * Handle for a GET /private/templates/$TEMPLATE_ID operation. */ -struct TALER_MERCHANT_TemplateGetHandle +struct TALER_MERCHANT_GetPrivateTemplateHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * Template identifier. + */ + char *template_id; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +58,25 @@ struct TALER_MERCHANT_TemplateGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_TemplateGetCallback cb; + TALER_MERCHANT_GetPrivateTemplateCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; /** * Function called when we're done processing the - * HTTP GET /templates/$ID request. + * HTTP GET /private/templates/$TEMPLATE_ID request. * - * @param cls the `struct TALER_MERCHANT_TemplateGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateTemplateHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,16 +85,16 @@ handle_get_template_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TemplateGetHandle *tgh = cls; + struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt = cls; const json_t *json = response; - struct TALER_MERCHANT_TemplateGetResponse tgr = { + struct TALER_MERCHANT_GetPrivateTemplateResponse tgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + gpt->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /templates/$ID response with status code %u\n", + "Got /private/templates/$TEMPLATE_ID response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -111,9 +119,9 @@ handle_get_template_finished (void *cls, NULL, NULL)) { tgr.details.ok.template_contract = contract; - tgh->cb (tgh->cb_cls, + gpt->cb (gpt->cb_cls, &tgr); - TALER_MERCHANT_template_get_cancel (tgh); + TALER_MERCHANT_get_private_template_cancel (gpt); return; } tgr.hr.http_status = 0; @@ -123,14 +131,12 @@ handle_get_template_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -139,63 +145,78 @@ handle_get_template_finished (void *cls, (int) tgr.hr.ec); break; } - tgh->cb (tgh->cb_cls, + gpt->cb (gpt->cb_cls, &tgr); - TALER_MERCHANT_template_get_cancel (tgh); + TALER_MERCHANT_get_private_template_cancel (gpt); } -struct TALER_MERCHANT_TemplateGetHandle * -TALER_MERCHANT_template_get ( +struct TALER_MERCHANT_GetPrivateTemplateHandle * +TALER_MERCHANT_get_private_template_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - TALER_MERCHANT_TemplateGetCallback cb, - void *cb_cls) + const char *url, + const char *template_id) +{ + struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt; + + gpt = GNUNET_new (struct TALER_MERCHANT_GetPrivateTemplateHandle); + gpt->ctx = ctx; + gpt->base_url = GNUNET_strdup (url); + gpt->template_id = GNUNET_strdup (template_id); + return gpt; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_template_start ( + struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt, + TALER_MERCHANT_GetPrivateTemplateCallback cb, + TALER_MERCHANT_GET_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TemplateGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_TemplateGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; + gpt->cb = cb; + gpt->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/templates/%s", - template_id); - tgh->url = TALER_url_join (backend_url, + gpt->template_id); + gpt->url = TALER_url_join (gpt->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gpt->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpt->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpt->job = GNUNET_CURL_job_add (gpt->ctx, eh, &handle_get_template_finished, - tgh); - return tgh; + gpt); + if (NULL == gpt->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_template_get_cancel ( - struct TALER_MERCHANT_TemplateGetHandle *tgh) +TALER_MERCHANT_get_private_template_cancel ( + struct TALER_MERCHANT_GetPrivateTemplateHandle *gpt) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != gpt->job) + { + GNUNET_CURL_job_cancel (gpt->job); + gpt->job = NULL; + } + GNUNET_free (gpt->url); + GNUNET_free (gpt->template_id); + GNUNET_free (gpt->base_url); + GNUNET_free (gpt); } + + +/* end of merchant_api_get-private-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-templates-new.c b/src/lib/merchant_api_get-private-templates-new.c @@ -1,265 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-templates-new.c - * @brief Implementation of the GET /private/templates request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-templates-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of templates we return. - */ -#define MAX_TEMPLATES 1024 - - -/** - * Handle for a GET /private/templates operation. - */ -struct TALER_MERCHANT_GetPrivateTemplatesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateTemplatesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse template information from @a ia. - * - * @param ia JSON array (or NULL!) with template data - * @param[in] tgr partially filled response - * @param gpth operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_templates (const json_t *ia, - struct TALER_MERCHANT_GetPrivateTemplatesResponse *tgr, - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth) -{ - unsigned int tmpl_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) tmpl_len) || - (tmpl_len > MAX_TEMPLATES) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry tmpl[ - GNUNET_NZL (tmpl_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry *ie = - &tmpl[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("template_id", - &ie->template_id), - GNUNET_JSON_spec_string ("template_description", - &ie->template_description), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - tgr->details.ok.templates_length = tmpl_len; - tgr->details.ok.templates = tmpl; - gpth->cb (gpth->cb_cls, - tgr); - gpth->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/templates request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateTemplatesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_templates_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateTemplatesResponse tgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/templates response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *templates; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("templates", - &templates), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_templates (templates, - &tgr, - gpth)) - { - TALER_MERCHANT_get_private_templates_cancel (gpth); - return; - } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) tgr.hr.ec); - break; - } - gpth->cb (gpth->cb_cls, - &tgr); - TALER_MERCHANT_get_private_templates_cancel (gpth); -} - - -struct TALER_MERCHANT_GetPrivateTemplatesHandle * -TALER_MERCHANT_get_private_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth; - - gpth = GNUNET_new (struct TALER_MERCHANT_GetPrivateTemplatesHandle); - gpth->ctx = ctx; - gpth->base_url = GNUNET_strdup (url); - return gpth; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_templates_start ( - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth, - TALER_MERCHANT_GetPrivateTemplatesCallback cb, - TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpth->cb = cb; - gpth->cb_cls = cb_cls; - gpth->url = TALER_url_join (gpth->base_url, - "private/templates", - NULL); - if (NULL == gpth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpth->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpth->job = GNUNET_CURL_job_add (gpth->ctx, - eh, - &handle_get_templates_finished, - gpth); - if (NULL == gpth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_templates_cancel ( - struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth) -{ - if (NULL != gpth->job) - { - GNUNET_CURL_job_cancel (gpth->job); - gpth->job = NULL; - } - GNUNET_free (gpth->url); - GNUNET_free (gpth->base_url); - GNUNET_free (gpth); -} - - -/* end of merchant_api_get-private-templates-new.c */ diff --git a/src/lib/merchant_api_get-private-templates.c b/src/lib/merchant_api_get-private-templates.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-templates.c - * @brief Implementation of the GET /templates request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_get-private-templates-new.c + * @brief Implementation of the GET /private/templates request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,10 +25,9 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-templates.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** @@ -38,12 +37,17 @@ /** - * Handle for a GET /templates operation. + * Handle for a GET /private/templates operation. */ -struct TALER_MERCHANT_TemplatesGetHandle +struct TALER_MERCHANT_GetPrivateTemplatesHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -55,18 +59,17 @@ struct TALER_MERCHANT_TemplatesGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_TemplatesGetCallback cb; + TALER_MERCHANT_GetPrivateTemplatesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; @@ -75,32 +78,36 @@ struct TALER_MERCHANT_TemplatesGetHandle * * @param ia JSON array (or NULL!) with template data * @param[in] tgr partially filled response - * @param tgh operation handle + * @param gpth operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_templates (const json_t *ia, - struct TALER_MERCHANT_TemplatesGetResponse *tgr, - struct TALER_MERCHANT_TemplatesGetHandle *tgh) + struct TALER_MERCHANT_GetPrivateTemplatesResponse *tgr, + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth) { unsigned int tmpl_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) tmpl_len) || + if ( (json_array_size (ia) != (size_t) tmpl_len) || (tmpl_len > MAX_TEMPLATES) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_TemplateEntry tmpl[GNUNET_NZL (tmpl_len)]; + struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry tmpl[ + GNUNET_NZL (tmpl_len)]; size_t index; json_t *value; json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_TemplateEntry *ie = &tmpl[index]; + struct TALER_MERCHANT_GetPrivateTemplatesTemplateEntry *ie = + &tmpl[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("template_id", &ie->template_id), + GNUNET_JSON_spec_string ("template_description", + &ie->template_description), GNUNET_JSON_spec_end () }; @@ -115,9 +122,9 @@ parse_templates (const json_t *ia, } tgr->details.ok.templates_length = tmpl_len; tgr->details.ok.templates = tmpl; - tgh->cb (tgh->cb_cls, - tgr); - tgh->cb = NULL; /* just to be sure */ + gpth->cb (gpth->cb_cls, + tgr); + gpth->cb = NULL; } return GNUNET_OK; } @@ -125,9 +132,9 @@ parse_templates (const json_t *ia, /** * Function called when we're done processing the - * HTTP /templates request. + * HTTP GET /private/templates request. * - * @param cls the `struct TALER_MERCHANT_TemplatesGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateTemplatesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -136,16 +143,16 @@ handle_get_templates_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TemplatesGetHandle *tgh = cls; + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth = cls; const json_t *json = response; - struct TALER_MERCHANT_TemplatesGetResponse tgr = { + struct TALER_MERCHANT_GetPrivateTemplatesResponse tgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + gpth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /templates response with status code %u\n", + "Got /private/templates response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -170,9 +177,9 @@ handle_get_templates_finished (void *cls, if (GNUNET_OK == parse_templates (templates, &tgr, - tgh)) + gpth)) { - TALER_MERCHANT_templates_get_cancel (tgh); + TALER_MERCHANT_get_private_templates_cancel (gpth); return; } tgr.hr.http_status = 0; @@ -182,10 +189,8 @@ handle_get_templates_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; default: - /* unexpected response code */ tgr.hr.ec = TALER_JSON_get_error_code (json); tgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -194,54 +199,67 @@ handle_get_templates_finished (void *cls, (int) tgr.hr.ec); break; } - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_templates_get_cancel (tgh); + gpth->cb (gpth->cb_cls, + &tgr); + TALER_MERCHANT_get_private_templates_cancel (gpth); } -struct TALER_MERCHANT_TemplatesGetHandle * -TALER_MERCHANT_templates_get ( +struct TALER_MERCHANT_GetPrivateTemplatesHandle * +TALER_MERCHANT_get_private_templates_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_TemplatesGetCallback cb, - void *cb_cls) + const char *url) +{ + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth; + + gpth = GNUNET_new (struct TALER_MERCHANT_GetPrivateTemplatesHandle); + gpth->ctx = ctx; + gpth->base_url = GNUNET_strdup (url); + return gpth; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_templates_start ( + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth, + TALER_MERCHANT_GetPrivateTemplatesCallback cb, + TALER_MERCHANT_GET_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TemplatesGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_TemplatesGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; - tgh->url = TALER_url_join (backend_url, - "private/templates", - NULL); - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_templates_finished, - tgh); - return tgh; + gpth->cb = cb; + gpth->cb_cls = cb_cls; + gpth->url = TALER_url_join (gpth->base_url, + "private/templates", + NULL); + if (NULL == gpth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpth->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpth->job = GNUNET_CURL_job_add (gpth->ctx, + eh, + &handle_get_templates_finished, + gpth); + if (NULL == gpth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_templates_get_cancel ( - struct TALER_MERCHANT_TemplatesGetHandle *tgh) +TALER_MERCHANT_get_private_templates_cancel ( + struct TALER_MERCHANT_GetPrivateTemplatesHandle *gpth) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != gpth->job) + { + GNUNET_CURL_job_cancel (gpth->job); + gpth->job = NULL; + } + GNUNET_free (gpth->url); + GNUNET_free (gpth->base_url); + GNUNET_free (gpth); } + + +/* end of merchant_api_get-private-templates-new.c */ diff --git a/src/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c b/src/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c @@ -1,242 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2023-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c - * @brief Implementation of the GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include \ - <taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. - */ -struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateTokenfamiliesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Token family slug. - */ - char *token_family_slug; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_token_family_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateTokenfamiliesResponse tfgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gptf->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/tokenfamilies/$SLUG response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("slug", - &tfgr.details.ok.slug), - GNUNET_JSON_spec_string ("name", - &tfgr.details.ok.name), - GNUNET_JSON_spec_string ("description", - &tfgr.details.ok.description), - GNUNET_JSON_spec_object_const ("description_i18n", - &tfgr.details.ok.description_i18n), - GNUNET_JSON_spec_object_const ("extra_data", - &tfgr.details.ok.extra_data), - GNUNET_JSON_spec_timestamp ("valid_after", - &tfgr.details.ok.valid_after), - GNUNET_JSON_spec_timestamp ("valid_before", - &tfgr.details.ok.valid_before), - GNUNET_JSON_spec_relative_time ("duation", - &tfgr.details.ok.duration), - GNUNET_JSON_spec_relative_time ("validity_granularity", - &tfgr.details.ok.validity_granularity), - GNUNET_JSON_spec_relative_time ("start_offset", - &tfgr.details.ok.start_offset), - GNUNET_JSON_spec_string ("kind", - &tfgr.details.ok.kind), - GNUNET_JSON_spec_uint64 ("issued", - &tfgr.details.ok.issued), - GNUNET_JSON_spec_uint64 ("used", - &tfgr.details.ok.used), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - gptf->cb (gptf->cb_cls, - &tfgr); - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_get_private_tokenfamilies_cancel (gptf); - return; - } - tfgr.hr.http_status = 0; - tfgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - tfgr.hr.ec = TALER_JSON_get_error_code (json); - tfgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - case MHD_HTTP_NOT_FOUND: - tfgr.hr.ec = TALER_JSON_get_error_code (json); - tfgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - /* unexpected response code */ - tfgr.hr.ec = TALER_JSON_get_error_code (json); - tfgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) tfgr.hr.ec); - break; - } - gptf->cb (gptf->cb_cls, - &tfgr); - TALER_MERCHANT_get_private_tokenfamilies_cancel (gptf); -} - - -struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle * -TALER_MERCHANT_get_private_tokenfamilies_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *token_family_slug) -{ - struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf; - - gptf = GNUNET_new (struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle); - gptf->ctx = ctx; - gptf->base_url = GNUNET_strdup (url); - gptf->token_family_slug = GNUNET_strdup (token_family_slug); - return gptf; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_tokenfamilies_start ( - struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf, - TALER_MERCHANT_GetPrivateTokenfamiliesCallback cb, - TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gptf->cb = cb; - gptf->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/tokenfamilies/%s", - gptf->token_family_slug); - gptf->url = TALER_url_join (gptf->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gptf->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gptf->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gptf->job = GNUNET_CURL_job_add (gptf->ctx, - eh, - &handle_get_token_family_finished, - gptf); - if (NULL == gptf->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_tokenfamilies_cancel ( - struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf) -{ - if (NULL != gptf->job) - { - GNUNET_CURL_job_cancel (gptf->job); - gptf->job = NULL; - } - GNUNET_free (gptf->url); - GNUNET_free (gptf->base_url); - GNUNET_free (gptf->token_family_slug); - GNUNET_free (gptf); -} - - -/* end of merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c */ diff --git a/src/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c b/src/lib/merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023-2024 Taler Systems SA + Copyright (C) 2023-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,31 +15,34 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG.c - * @brief Implementation of the GET /tokenfamily/$ID request of the merchant's HTTP API - * @author Christian Blättler + * @file merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c + * @brief Implementation of the GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> -#include <gnunet/gnunet_common.h> -#include <gnunet/gnunet_json_lib.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include \ + <taler/taler-merchant/get-private-tokenfamilies-TOKEN_FAMILY_SLUG.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /tokenfamilies/$SLUG operation. + * Handle for a GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG operation. */ -struct TALER_MERCHANT_TokenFamilyGetHandle +struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -51,26 +54,30 @@ struct TALER_MERCHANT_TokenFamilyGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_TokenFamilyGetCallback cb; + TALER_MERCHANT_GetPrivateTokenfamiliesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Token family slug. + */ + char *token_family_slug; }; /** * Function called when we're done processing the - * HTTP GET /tokenfamilies/$ID request. + * HTTP GET /private/tokenfamilies/$TOKEN_FAMILY_SLUG request. * - * @param cls the `struct TALER_MERCHANT_TokenFamilyGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -79,49 +86,48 @@ handle_get_token_family_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TokenFamilyGetHandle *handle = cls; + struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf = cls; const json_t *json = response; - struct TALER_MERCHANT_TokenFamilyGetResponse res = { + struct TALER_MERCHANT_GetPrivateTokenfamiliesResponse tfgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - handle->job = NULL; + gptf->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /tokenfamilies/$ID response with status code %u\n", + "Got /private/tokenfamilies/$SLUG response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_OK: { - // Parse token family response struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("slug", - &res.details.ok.slug), + &tfgr.details.ok.slug), GNUNET_JSON_spec_string ("name", - &res.details.ok.name), + &tfgr.details.ok.name), GNUNET_JSON_spec_string ("description", - &res.details.ok.description), + &tfgr.details.ok.description), GNUNET_JSON_spec_object_const ("description_i18n", - &res.details.ok.description_i18n), + &tfgr.details.ok.description_i18n), GNUNET_JSON_spec_object_const ("extra_data", - &res.details.ok.extra_data), + &tfgr.details.ok.extra_data), GNUNET_JSON_spec_timestamp ("valid_after", - &res.details.ok.valid_after), + &tfgr.details.ok.valid_after), GNUNET_JSON_spec_timestamp ("valid_before", - &res.details.ok.valid_before), + &tfgr.details.ok.valid_before), GNUNET_JSON_spec_relative_time ("duation", - &res.details.ok.duration), + &tfgr.details.ok.duration), GNUNET_JSON_spec_relative_time ("validity_granularity", - &res.details.ok.validity_granularity), + &tfgr.details.ok.validity_granularity), GNUNET_JSON_spec_relative_time ("start_offset", - &res.details.ok.start_offset), + &tfgr.details.ok.start_offset), GNUNET_JSON_spec_string ("kind", - &res.details.ok.kind), + &tfgr.details.ok.kind), GNUNET_JSON_spec_uint64 ("issued", - &res.details.ok.issued), + &tfgr.details.ok.issued), GNUNET_JSON_spec_uint64 ("used", - &res.details.ok.used), + &tfgr.details.ok.used), GNUNET_JSON_spec_end () }; @@ -130,89 +136,107 @@ handle_get_token_family_finished (void *cls, spec, NULL, NULL)) { - handle->cb (handle->cb_cls, - &res); + gptf->cb (gptf->cb_cls, + &tfgr); GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_token_family_get_cancel (handle); + TALER_MERCHANT_get_private_tokenfamilies_cancel (gptf); return; } - res.hr.http_status = 0; - res.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + tfgr.hr.http_status = 0; + tfgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); + tfgr.hr.ec = TALER_JSON_get_error_code (json); + tfgr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); + tfgr.hr.ec = TALER_JSON_get_error_code (json); + tfgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ - res.hr.ec = TALER_JSON_get_error_code (json); - res.hr.hint = TALER_JSON_get_error_hint (json); + tfgr.hr.ec = TALER_JSON_get_error_code (json); + tfgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) res.hr.ec); + (int) tfgr.hr.ec); break; } + gptf->cb (gptf->cb_cls, + &tfgr); + TALER_MERCHANT_get_private_tokenfamilies_cancel (gptf); } -struct TALER_MERCHANT_TokenFamilyGetHandle * -TALER_MERCHANT_token_family_get ( +struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle * +TALER_MERCHANT_get_private_tokenfamilies_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *token_family_slug, - TALER_MERCHANT_TokenFamilyGetCallback cb, - void *cb_cls) + const char *url, + const char *token_family_slug) +{ + struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf; + + gptf = GNUNET_new (struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle); + gptf->ctx = ctx; + gptf->base_url = GNUNET_strdup (url); + gptf->token_family_slug = GNUNET_strdup (token_family_slug); + return gptf; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_tokenfamilies_start ( + struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf, + TALER_MERCHANT_GetPrivateTokenfamiliesCallback cb, + TALER_MERCHANT_GET_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TokenFamilyGetHandle *handle; CURL *eh; - handle = GNUNET_new (struct TALER_MERCHANT_TokenFamilyGetHandle); - handle->ctx = ctx; - handle->cb = cb; - handle->cb_cls = cb_cls; + gptf->cb = cb; + gptf->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/tokenfamilies/%s", - token_family_slug); - handle->url = TALER_url_join (backend_url, - path, - NULL); + gptf->token_family_slug); + gptf->url = TALER_url_join (gptf->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == handle->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (handle); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - handle->url); - eh = TALER_MERCHANT_curl_easy_get_ (handle->url); - handle->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_token_family_finished, - handle); - return handle; + if (NULL == gptf->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gptf->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gptf->job = GNUNET_CURL_job_add (gptf->ctx, + eh, + &handle_get_token_family_finished, + gptf); + if (NULL == gptf->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_token_family_get_cancel ( - struct TALER_MERCHANT_TokenFamilyGetHandle *handle) +TALER_MERCHANT_get_private_tokenfamilies_cancel ( + struct TALER_MERCHANT_GetPrivateTokenfamiliesHandle *gptf) { - if (NULL != handle->job) - GNUNET_CURL_job_cancel (handle->job); - GNUNET_free (handle->url); - GNUNET_free (handle); + if (NULL != gptf->job) + { + GNUNET_CURL_job_cancel (gptf->job); + gptf->job = NULL; + } + GNUNET_free (gptf->url); + GNUNET_free (gptf->base_url); + GNUNET_free (gptf->token_family_slug); + GNUNET_free (gptf); } + + +/* end of merchant_api_get-private-tokenfamilies-TOKEN_FAMILY_SLUG-new.c */ diff --git a/src/lib/merchant_api_get-private-transfers-new.c b/src/lib/merchant_api_get-private-transfers-new.c @@ -1,417 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-transfers-new.c - * @brief Implementation of the GET /private/transfers request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-transfers-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of transfers we return. - */ -#define MAX_TRANSFERS 1024 - - -/** - * Handle for a GET /private/transfers operation. - */ -struct TALER_MERCHANT_GetPrivateTransfersHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateTransfersCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Payto URI filter (URL-encoded), or NULL. - */ - char *payto_uri_enc; - - /** - * Before timestamp filter, or GNUNET_TIME_UNIT_FOREVER_TS. - */ - struct GNUNET_TIME_Timestamp before; - - /** - * After timestamp filter, or GNUNET_TIME_UNIT_ZERO_TS. - */ - struct GNUNET_TIME_Timestamp after; - - /** - * Limit on number of results (0 = default). - */ - int64_t limit; - - /** - * Offset for pagination. - */ - uint64_t offset; - - /** - * Expected filter. - */ - enum TALER_EXCHANGE_YesNoAll expected; - - /** - * True if offset was explicitly set. - */ - bool have_offset; -}; - - -/** - * Parse transfer information from @a transfers_arr. - * - * @param transfers_arr JSON array with transfer data - * @param[in,out] gtr response to fill - * @param gth operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_transfers ( - const json_t *transfers_arr, - struct TALER_MERCHANT_GetPrivateTransfersResponse *gtr, - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth) -{ - unsigned int tds_length = (unsigned int) json_array_size (transfers_arr); - - if ( (json_array_size (transfers_arr) != (size_t) tds_length) || - (tds_length > MAX_TRANSFERS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateTransfersTransferData tds[ - GNUNET_NZL (tds_length)]; - size_t index; - json_t *value; - - json_array_foreach (transfers_arr, index, value) { - struct TALER_MERCHANT_GetPrivateTransfersTransferData *td = &tds[index]; - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_amount_any ("credit_amount", - &td->credit_amount), - GNUNET_JSON_spec_fixed_auto ("wtid", - &td->wtid), - TALER_JSON_spec_full_payto_uri ("payto_uri", - &td->payto_uri), - TALER_JSON_spec_web_url ("exchange_url", - &td->exchange_url), - GNUNET_JSON_spec_uint64 ("transfer_serial_id", - &td->credit_serial), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ("execution_time", - &td->execution_time), - NULL), - GNUNET_JSON_spec_bool ("expected", - &td->expected), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - gtr->details.ok.transfers_length = tds_length; - gtr->details.ok.transfers = tds; - gth->cb (gth->cb_cls, - gtr); - gth->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/transfers request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateTransfersHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_transfers_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateTransfersResponse gtr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/transfers response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *transfers; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("transfers", - &transfers), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - gtr.hr.http_status = 0; - gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_transfers (transfers, - &gtr, - gth)) - { - TALER_MERCHANT_get_private_transfers_cancel (gth); - return; - } - gtr.hr.http_status = 0; - gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - gtr.hr.ec = TALER_JSON_get_error_code (json); - gtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - gtr.hr.ec = TALER_JSON_get_error_code (json); - gtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - gtr.hr.ec = TALER_JSON_get_error_code (json); - gtr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) gtr.hr.ec); - break; - } - gth->cb (gth->cb_cls, - &gtr); - TALER_MERCHANT_get_private_transfers_cancel (gth); -} - - -struct TALER_MERCHANT_GetPrivateTransfersHandle * -TALER_MERCHANT_get_private_transfers_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth; - - gth = GNUNET_new (struct TALER_MERCHANT_GetPrivateTransfersHandle); - gth->ctx = ctx; - gth->base_url = GNUNET_strdup (url); - gth->expected = TALER_EXCHANGE_YNA_ALL; - gth->before = GNUNET_TIME_UNIT_FOREVER_TS; - gth->after = GNUNET_TIME_UNIT_ZERO_TS; - gth->offset = UINT64_MAX; - return gth; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_get_private_transfers_set_options_ ( - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, - unsigned int num_options, - const struct TALER_MERCHANT_GetPrivateTransfersOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - const struct TALER_MERCHANT_GetPrivateTransfersOptionValue *opt = - &options[i]; - - switch (opt->option) - { - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI: - GNUNET_free (gth->payto_uri_enc); - gth->payto_uri_enc = TALER_urlencode ( - opt->details.payto_uri.full_payto); - break; - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE: - gth->before = opt->details.before; - break; - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER: - gth->after = opt->details.after; - break; - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT: - gth->limit = opt->details.limit; - break; - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET: - gth->offset = opt->details.offset; - gth->have_offset = true; - break; - case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED: - gth->expected = opt->details.expected; - break; - default: - GNUNET_break (0); - return GNUNET_NO; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_transfers_start ( - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, - TALER_MERCHANT_GetPrivateTransfersCallback cb, - TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gth->cb = cb; - gth->cb_cls = cb_cls; - { - const char *expected_s = NULL; - char limit_s[30]; - char offset_s[30]; - char before_s[30]; - char after_s[30]; - - if (TALER_EXCHANGE_YNA_ALL != gth->expected) - expected_s = TALER_yna_to_string (gth->expected); - GNUNET_snprintf (limit_s, - sizeof (limit_s), - "%lld", - (long long) gth->limit); - GNUNET_snprintf (offset_s, - sizeof (offset_s), - "%lld", - (unsigned long long) gth->offset); - GNUNET_snprintf (before_s, - sizeof (before_s), - "%llu", - (unsigned long long) GNUNET_TIME_timestamp_to_s ( - gth->before)); - GNUNET_snprintf (after_s, - sizeof (after_s), - "%llu", - (unsigned long long) GNUNET_TIME_timestamp_to_s ( - gth->after)); - gth->url = TALER_url_join (gth->base_url, - "private/transfers", - "payto_uri", - gth->payto_uri_enc, - "expected", - expected_s, - "limit", - 0 != gth->limit - ? limit_s - : NULL, - "offset", - (gth->have_offset && - (UINT64_MAX != gth->offset)) - ? offset_s - : NULL, - "before", - GNUNET_TIME_absolute_is_never ( - gth->before.abs_time) - ? NULL - : before_s, - "after", - GNUNET_TIME_absolute_is_zero ( - gth->after.abs_time) - ? NULL - : after_s, - NULL); - } - if (NULL == gth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gth->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gth->job = GNUNET_CURL_job_add (gth->ctx, - eh, - &handle_get_transfers_finished, - gth); - if (NULL == gth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_transfers_cancel ( - struct TALER_MERCHANT_GetPrivateTransfersHandle *gth) -{ - if (NULL != gth->job) - { - GNUNET_CURL_job_cancel (gth->job); - gth->job = NULL; - } - GNUNET_free (gth->url); - GNUNET_free (gth->base_url); - GNUNET_free (gth->payto_uri_enc); - GNUNET_free (gth); -} - - -/* end of merchant_api_get-private-transfers-new.c */ diff --git a/src/lib/merchant_api_get-private-transfers.c b/src/lib/merchant_api_get-private-transfers.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-transfers.c - * @brief Implementation of the GET /transfers request of the merchant's HTTP API - * @author Marcello Stanisci + * @file merchant_api_get-private-transfers-new.c + * @brief Implementation of the GET /private/transfers request * @author Christian Grothoff */ #include "taler/platform.h" @@ -26,21 +25,29 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <taler/taler-merchant/get-private-transfers.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * @brief A Handle for tracking wire transfers. + * Maximum number of transfers we return. */ -struct TALER_MERCHANT_GetTransfersHandle +#define MAX_TRANSFERS 1024 + + +/** + * Handle for a GET /private/transfers operation. + */ +struct TALER_MERCHANT_GetPrivateTransfersHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -52,46 +59,150 @@ struct TALER_MERCHANT_GetTransfersHandle /** * Function to call with the result. */ - TALER_MERCHANT_GetTransfersCallback cb; + TALER_MERCHANT_GetPrivateTransfersCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Payto URI filter (URL-encoded), or NULL. + */ + char *payto_uri_enc; + + /** + * Before timestamp filter, or GNUNET_TIME_UNIT_FOREVER_TS. + */ + struct GNUNET_TIME_Timestamp before; + + /** + * After timestamp filter, or GNUNET_TIME_UNIT_ZERO_TS. + */ + struct GNUNET_TIME_Timestamp after; + + /** + * Limit on number of results (0 = default). + */ + int64_t limit; + + /** + * Offset for pagination. + */ + uint64_t offset; + + /** + * Expected filter. + */ + enum TALER_EXCHANGE_YesNoAll expected; + + /** + * True if offset was explicitly set. + */ + bool have_offset; }; /** + * Parse transfer information from @a transfers_arr. + * + * @param transfers_arr JSON array with transfer data + * @param[in,out] gtr response to fill + * @param gth operation handle + * @return #GNUNET_OK on success + */ +static enum GNUNET_GenericReturnValue +parse_transfers ( + const json_t *transfers_arr, + struct TALER_MERCHANT_GetPrivateTransfersResponse *gtr, + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth) +{ + unsigned int tds_length = (unsigned int) json_array_size (transfers_arr); + + if ( (json_array_size (transfers_arr) != (size_t) tds_length) || + (tds_length > MAX_TRANSFERS) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_GetPrivateTransfersTransferData tds[ + GNUNET_NZL (tds_length)]; + size_t index; + json_t *value; + + json_array_foreach (transfers_arr, index, value) { + struct TALER_MERCHANT_GetPrivateTransfersTransferData *td = &tds[index]; + struct GNUNET_JSON_Specification ispec[] = { + TALER_JSON_spec_amount_any ("credit_amount", + &td->credit_amount), + GNUNET_JSON_spec_fixed_auto ("wtid", + &td->wtid), + TALER_JSON_spec_full_payto_uri ("payto_uri", + &td->payto_uri), + TALER_JSON_spec_web_url ("exchange_url", + &td->exchange_url), + GNUNET_JSON_spec_uint64 ("transfer_serial_id", + &td->credit_serial), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_timestamp ("execution_time", + &td->execution_time), + NULL), + GNUNET_JSON_spec_bool ("expected", + &td->expected), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + ispec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + gtr->details.ok.transfers_length = tds_length; + gtr->details.ok.transfers = tds; + gth->cb (gth->cb_cls, + gtr); + gth->cb = NULL; + } + return GNUNET_OK; +} + + +/** * Function called when we're done processing the - * HTTP GET /transfers request. + * HTTP GET /private/transfers request. * - * @param cls the `struct TALER_MERCHANT_GetTransfersHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateTransfersHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_transfers_get_finished (void *cls, +handle_get_transfers_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_GetTransfersHandle *gth = cls; + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth = cls; const json_t *json = response; - struct TALER_MERCHANT_GetTransfersResponse gtr = { + struct TALER_MERCHANT_GetPrivateTransfersResponse gtr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; gth->job = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got /private/transfers response with status code %u\n", + (unsigned int) response_code); switch (response_code) { - case 0: - gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; case MHD_HTTP_OK: { const json_t *transfers; @@ -106,200 +217,190 @@ handle_transfers_get_finished (void *cls, spec, NULL, NULL)) { - GNUNET_break_op (0); gtr.hr.http_status = 0; gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - + if (GNUNET_OK == + parse_transfers (transfers, + &gtr, + gth)) { - size_t tds_length; - struct TALER_MERCHANT_TransferData *tds; - json_t *transfer; - size_t i; - bool ok; - - tds_length = json_array_size (transfers); - tds = GNUNET_new_array (tds_length, - struct TALER_MERCHANT_TransferData); - ok = true; - json_array_foreach (transfers, i, transfer) { - struct TALER_MERCHANT_TransferData *td = &tds[i]; - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_amount_any ("credit_amount", - &td->credit_amount), - GNUNET_JSON_spec_fixed_auto ("wtid", - &td->wtid), - TALER_JSON_spec_full_payto_uri ("payto_uri", - &td->payto_uri), - TALER_JSON_spec_web_url ("exchange_url", - &td->exchange_url), - GNUNET_JSON_spec_uint64 ("transfer_serial_id", - &td->credit_serial), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ("execution_time", - &td->execution_time), - NULL), - GNUNET_JSON_spec_bool ("expected", - &td->expected), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (transfer, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - ok = false; - break; - } - } - - if (! ok) - { - GNUNET_break_op (0); - GNUNET_free (tds); - gtr.hr.http_status = 0; - gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - gtr.details.ok.transfers = tds; - gtr.details.ok.transfers_length = tds_length; - gth->cb (gth->cb_cls, - &gtr); - GNUNET_free (tds); - TALER_MERCHANT_transfers_get_cancel (gth); + TALER_MERCHANT_get_private_transfers_cancel (gth); return; } + gtr.hr.http_status = 0; + gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; } case MHD_HTTP_UNAUTHORIZED: gtr.hr.ec = TALER_JSON_get_error_code (json); gtr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the application */ gtr.hr.ec = TALER_JSON_get_error_code (json); gtr.hr.hint = TALER_JSON_get_error_hint (json); break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ + default: gtr.hr.ec = TALER_JSON_get_error_code (json); gtr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - /* unexpected response code */ - GNUNET_break_op (0); - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &gtr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, (int) gtr.hr.ec); - gtr.hr.http_status = 0; break; } gth->cb (gth->cb_cls, &gtr); - TALER_MERCHANT_transfers_get_cancel (gth); + TALER_MERCHANT_get_private_transfers_cancel (gth); } -struct TALER_MERCHANT_GetTransfersHandle * -TALER_MERCHANT_transfers_get ( +struct TALER_MERCHANT_GetPrivateTransfersHandle * +TALER_MERCHANT_get_private_transfers_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - struct TALER_FullPayto payto_uri, - const struct GNUNET_TIME_Timestamp before, - const struct GNUNET_TIME_Timestamp after, - int64_t limit, - uint64_t offset, - enum TALER_EXCHANGE_YesNoAll expected, - TALER_MERCHANT_GetTransfersCallback cb, - void *cb_cls) + const char *url) { - struct TALER_MERCHANT_GetTransfersHandle *gth; - CURL *eh; - const char *expected_s = NULL; - char limit_s[30]; - char offset_s[30]; - char before_s[30]; - char after_s[30]; + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth; - gth = GNUNET_new (struct TALER_MERCHANT_GetTransfersHandle); + gth = GNUNET_new (struct TALER_MERCHANT_GetPrivateTransfersHandle); gth->ctx = ctx; + gth->base_url = GNUNET_strdup (url); + gth->expected = TALER_EXCHANGE_YNA_ALL; + gth->before = GNUNET_TIME_UNIT_FOREVER_TS; + gth->after = GNUNET_TIME_UNIT_ZERO_TS; + gth->offset = UINT64_MAX; + return gth; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_get_private_transfers_set_options_ ( + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, + unsigned int num_options, + const struct TALER_MERCHANT_GetPrivateTransfersOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + const struct TALER_MERCHANT_GetPrivateTransfersOptionValue *opt = + &options[i]; + + switch (opt->option) + { + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_PAYTO_URI: + GNUNET_free (gth->payto_uri_enc); + gth->payto_uri_enc = TALER_urlencode ( + opt->details.payto_uri.full_payto); + break; + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_BEFORE: + gth->before = opt->details.before; + break; + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_AFTER: + gth->after = opt->details.after; + break; + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_LIMIT: + gth->limit = opt->details.limit; + break; + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_OFFSET: + gth->offset = opt->details.offset; + gth->have_offset = true; + break; + case TALER_MERCHANT_GET_PRIVATE_TRANSFERS_OPTION_EXPECTED: + gth->expected = opt->details.expected; + break; + default: + GNUNET_break (0); + return GNUNET_NO; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_transfers_start ( + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth, + TALER_MERCHANT_GetPrivateTransfersCallback cb, + TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls) +{ + CURL *eh; + gth->cb = cb; gth->cb_cls = cb_cls; - expected_s = TALER_yna_to_string (expected); - GNUNET_snprintf (limit_s, - sizeof (limit_s), - "%lld", - (long long) limit); - GNUNET_snprintf (offset_s, - sizeof (offset_s), - "%lld", - (unsigned long long) offset); - GNUNET_snprintf (before_s, - sizeof (before_s), - "%llu", - (unsigned long long) GNUNET_TIME_timestamp_to_s (before)); - GNUNET_snprintf (after_s, - sizeof (after_s), - "%llu", - (unsigned long long) GNUNET_TIME_timestamp_to_s (after)); { - char *enc_payto = TALER_urlencode (payto_uri.full_payto); + const char *expected_s = NULL; + char limit_s[30]; + char offset_s[30]; + char before_s[30]; + char after_s[30]; - gth->url = TALER_url_join (backend_url, + if (TALER_EXCHANGE_YNA_ALL != gth->expected) + expected_s = TALER_yna_to_string (gth->expected); + GNUNET_snprintf (limit_s, + sizeof (limit_s), + "%lld", + (long long) gth->limit); + GNUNET_snprintf (offset_s, + sizeof (offset_s), + "%lld", + (unsigned long long) gth->offset); + GNUNET_snprintf (before_s, + sizeof (before_s), + "%llu", + (unsigned long long) GNUNET_TIME_timestamp_to_s ( + gth->before)); + GNUNET_snprintf (after_s, + sizeof (after_s), + "%llu", + (unsigned long long) GNUNET_TIME_timestamp_to_s ( + gth->after)); + gth->url = TALER_url_join (gth->base_url, "private/transfers", "payto_uri", - enc_payto, + gth->payto_uri_enc, "expected", - (TALER_EXCHANGE_YNA_ALL != expected) - ? expected_s - : NULL, + expected_s, "limit", - 0 != limit + 0 != gth->limit ? limit_s : NULL, "offset", - ((0 != offset) && (UINT64_MAX != offset)) + (gth->have_offset && + (UINT64_MAX != gth->offset)) ? offset_s : NULL, "before", - GNUNET_TIME_absolute_is_never (before.abs_time) + GNUNET_TIME_absolute_is_never ( + gth->before.abs_time) ? NULL : before_s, "after", - GNUNET_TIME_absolute_is_zero (after.abs_time) + GNUNET_TIME_absolute_is_zero ( + gth->after.abs_time) ? NULL : after_s, NULL); - GNUNET_free (enc_payto); } if (NULL == gth->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (gth); - return NULL; - } + return TALER_EC_GENERIC_CONFIGURATION_INVALID; eh = TALER_MERCHANT_curl_easy_get_ (gth->url); - gth->job = GNUNET_CURL_job_add (ctx, + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gth->job = GNUNET_CURL_job_add (gth->ctx, eh, - &handle_transfers_get_finished, + &handle_get_transfers_finished, gth); - return gth; + if (NULL == gth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_transfers_get_cancel ( - struct TALER_MERCHANT_GetTransfersHandle *gth) +TALER_MERCHANT_get_private_transfers_cancel ( + struct TALER_MERCHANT_GetPrivateTransfersHandle *gth) { if (NULL != gth->job) { @@ -307,8 +408,10 @@ TALER_MERCHANT_transfers_get_cancel ( gth->job = NULL; } GNUNET_free (gth->url); + GNUNET_free (gth->base_url); + GNUNET_free (gth->payto_uri_enc); GNUNET_free (gth); } -/* end of merchant_api_get_transfers.c */ +/* end of merchant_api_get-private-transfers-new.c */ diff --git a/src/lib/merchant_api_get-private-units-UNIT-new.c b/src/lib/merchant_api_get-private-units-UNIT-new.c @@ -1,274 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-units-UNIT-new.c - * @brief Implementation of the GET /private/units/$UNIT request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-units-UNIT-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/units/$UNIT operation. - */ -struct TALER_MERCHANT_GetPrivateUnitHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateUnitCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Unit identifier. - */ - char *unit_id; -}; - - -/** - * Parse the JSON response into the unit entry. - * - * @param json full JSON reply - * @param ugr response descriptor to populate - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_unit (const json_t *json, - struct TALER_MERCHANT_GetPrivateUnitResponse *ugr) -{ - struct TALER_MERCHANT_UnitEntry *entry = &ugr->details.ok.unit; - const char *unit; - const char *unit_name_long; - const char *unit_name_short; - const json_t *unit_name_long_i18n = NULL; - const json_t *unit_name_short_i18n = NULL; - bool unit_allow_fraction; - bool unit_active; - bool unit_builtin; - uint32_t unit_precision_level; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("unit", - &unit), - GNUNET_JSON_spec_string ("unit_name_long", - &unit_name_long), - GNUNET_JSON_spec_string ("unit_name_short", - &unit_name_short), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("unit_name_long_i18n", - &unit_name_long_i18n), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("unit_name_short_i18n", - &unit_name_short_i18n), - NULL), - GNUNET_JSON_spec_bool ("unit_allow_fraction", - &unit_allow_fraction), - GNUNET_JSON_spec_uint32 ("unit_precision_level", - &unit_precision_level), - GNUNET_JSON_spec_bool ("unit_active", - &unit_active), - GNUNET_JSON_spec_bool ("unit_builtin", - &unit_builtin), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, - NULL)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } - GNUNET_JSON_parse_free (spec); - entry->unit = unit; - entry->unit_name_long = unit_name_long; - entry->unit_name_short = unit_name_short; - entry->unit_name_long_i18n = unit_name_long_i18n; - entry->unit_name_short_i18n = unit_name_short_i18n; - entry->unit_allow_fraction = unit_allow_fraction; - entry->unit_precision_level = unit_precision_level; - entry->unit_active = unit_active; - entry->unit_builtin = unit_builtin; - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/units/$UNIT request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateUnitHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_unit_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateUnitHandle *gpu = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateUnitResponse ugr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpu->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/units/$UNIT response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - if (GNUNET_OK != - parse_unit (json, - &ugr)) - { - ugr.hr.http_status = 0; - ugr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - gpu->cb (gpu->cb_cls, - &ugr); - TALER_MERCHANT_get_private_unit_cancel (gpu); - return; - case MHD_HTTP_UNAUTHORIZED: - case MHD_HTTP_FORBIDDEN: - case MHD_HTTP_NOT_FOUND: - ugr.hr.ec = TALER_JSON_get_error_code (json); - ugr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - ugr.hr.ec = TALER_JSON_get_error_code (json); - ugr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ugr.hr.ec); - break; - } - gpu->cb (gpu->cb_cls, - &ugr); - TALER_MERCHANT_get_private_unit_cancel (gpu); -} - - -struct TALER_MERCHANT_GetPrivateUnitHandle * -TALER_MERCHANT_get_private_unit_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *unit_id) -{ - struct TALER_MERCHANT_GetPrivateUnitHandle *gpu; - - gpu = GNUNET_new (struct TALER_MERCHANT_GetPrivateUnitHandle); - gpu->ctx = ctx; - gpu->base_url = GNUNET_strdup (url); - gpu->unit_id = GNUNET_strdup (unit_id); - return gpu; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_unit_start ( - struct TALER_MERCHANT_GetPrivateUnitHandle *gpu, - TALER_MERCHANT_GetPrivateUnitCallback cb, - TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpu->cb = cb; - gpu->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/units/%s", - gpu->unit_id); - gpu->url = TALER_url_join (gpu->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gpu->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpu->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpu->job = GNUNET_CURL_job_add (gpu->ctx, - eh, - &handle_get_unit_finished, - gpu); - if (NULL == gpu->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_unit_cancel ( - struct TALER_MERCHANT_GetPrivateUnitHandle *gpu) -{ - if (NULL != gpu->job) - { - GNUNET_CURL_job_cancel (gpu->job); - gpu->job = NULL; - } - GNUNET_free (gpu->url); - GNUNET_free (gpu->base_url); - GNUNET_free (gpu->unit_id); - GNUNET_free (gpu); -} - - -/* end of merchant_api_get-private-units-UNIT-new.c */ diff --git a/src/lib/merchant_api_get-private-units-UNIT.c b/src/lib/merchant_api_get-private-units-UNIT.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -11,58 +11,69 @@ A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> + TALER; see the file COPYING.LGPL. If not, see + <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-units-UNIT.c - * @brief Implementation of GET /private/units/$ID - * @author Bohdan Potuzhnyi + * @file merchant_api_get-private-units-UNIT-new.c + * @brief Implementation of the GET /private/units/$UNIT request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-units-UNIT.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> /** - * Handle for a GET /private/units/$ID operation. + * Handle for a GET /private/units/$UNIT operation. */ -struct TALER_MERCHANT_UnitGetHandle +struct TALER_MERCHANT_GetPrivateUnitHandle { /** - * Fully qualified request URL. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * In-flight job handle. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** - * Callback to invoke with the response. + * Function to call with the result. */ - TALER_MERCHANT_UnitGetCallback cb; + TALER_MERCHANT_GetPrivateUnitCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls; /** - * Execution context. + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Unit identifier. + */ + char *unit_id; }; /** - * Parse the JSON response into @a ugr. + * Parse the JSON response into the unit entry. * * @param json full JSON reply * @param ugr response descriptor to populate @@ -70,7 +81,7 @@ struct TALER_MERCHANT_UnitGetHandle */ static enum GNUNET_GenericReturnValue parse_unit (const json_t *json, - struct TALER_MERCHANT_UnitGetResponse *ugr) + struct TALER_MERCHANT_GetPrivateUnitResponse *ugr) { struct TALER_MERCHANT_UnitEntry *entry = &ugr->details.ok.unit; const char *unit; @@ -133,27 +144,28 @@ parse_unit (const json_t *json, /** - * Called once the HTTP request completes. + * Function called when we're done processing the + * HTTP GET /private/units/$UNIT request. * - * @param cls operation handle - * @param response_code HTTP status (0 on client-side errors) - * @param response parsed JSON reply (NULL if parsing failed) + * @param cls the `struct TALER_MERCHANT_GetPrivateUnitHandle` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON */ static void handle_get_unit_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_UnitGetHandle *ugh = cls; + struct TALER_MERCHANT_GetPrivateUnitHandle *gpu = cls; const json_t *json = response; - struct TALER_MERCHANT_UnitGetResponse ugr = { + struct TALER_MERCHANT_GetPrivateUnitResponse ugr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - ugh->job = NULL; + gpu->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GET /private/units/$ID finished with status %u\n", + "Got /private/units/$UNIT response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -166,9 +178,9 @@ handle_get_unit_finished (void *cls, ugr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } - ugh->cb (ugh->cb_cls, + gpu->cb (gpu->cb_cls, &ugr); - TALER_MERCHANT_unit_get_cancel (ugh); + TALER_MERCHANT_get_private_unit_cancel (gpu); return; case MHD_HTTP_UNAUTHORIZED: case MHD_HTTP_FORBIDDEN: @@ -176,74 +188,87 @@ handle_get_unit_finished (void *cls, ugr.hr.ec = TALER_JSON_get_error_code (json); ugr.hr.hint = TALER_JSON_get_error_hint (json); break; - case 0: - ugr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; default: ugr.hr.ec = TALER_JSON_get_error_code (json); ugr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unexpected response %u/%d for GET /private/units/$ID\n", + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d\n", (unsigned int) response_code, (int) ugr.hr.ec); break; } - ugh->cb (ugh->cb_cls, + gpu->cb (gpu->cb_cls, &ugr); - TALER_MERCHANT_unit_get_cancel (ugh); + TALER_MERCHANT_get_private_unit_cancel (gpu); } -struct TALER_MERCHANT_UnitGetHandle * -TALER_MERCHANT_unit_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *unit_id, - TALER_MERCHANT_UnitGetCallback cb, - void *cb_cls) +struct TALER_MERCHANT_GetPrivateUnitHandle * +TALER_MERCHANT_get_private_unit_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *unit_id) +{ + struct TALER_MERCHANT_GetPrivateUnitHandle *gpu; + + gpu = GNUNET_new (struct TALER_MERCHANT_GetPrivateUnitHandle); + gpu->ctx = ctx; + gpu->base_url = GNUNET_strdup (url); + gpu->unit_id = GNUNET_strdup (unit_id); + return gpu; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_unit_start ( + struct TALER_MERCHANT_GetPrivateUnitHandle *gpu, + TALER_MERCHANT_GetPrivateUnitCallback cb, + TALER_MERCHANT_GET_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_UnitGetHandle *ugh; CURL *eh; - char *path; - - GNUNET_asprintf (&path, - "private/units/%s", - unit_id); - ugh = GNUNET_new (struct TALER_MERCHANT_UnitGetHandle); - ugh->ctx = ctx; - ugh->cb = cb; - ugh->cb_cls = cb_cls; - ugh->url = TALER_url_join (backend_url, - path, - NULL); - GNUNET_free (path); - if (NULL == ugh->url) + + gpu->cb = cb; + gpu->cb_cls = cb_cls; { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to build /private/units/%s URL\n", - unit_id); - GNUNET_free (ugh); - return NULL; + char *path; + + GNUNET_asprintf (&path, + "private/units/%s", + gpu->unit_id); + gpu->url = TALER_url_join (gpu->base_url, + path, + NULL); + GNUNET_free (path); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - ugh->url); - eh = TALER_MERCHANT_curl_easy_get_ (ugh->url); - ugh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gpu->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpu->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpu->job = GNUNET_CURL_job_add (gpu->ctx, eh, &handle_get_unit_finished, - ugh); - return ugh; + gpu); + if (NULL == gpu->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_unit_get_cancel (struct TALER_MERCHANT_UnitGetHandle *ugh) +TALER_MERCHANT_get_private_unit_cancel ( + struct TALER_MERCHANT_GetPrivateUnitHandle *gpu) { - if (NULL != ugh->job) - GNUNET_CURL_job_cancel (ugh->job); - GNUNET_free (ugh->url); - GNUNET_free (ugh); + if (NULL != gpu->job) + { + GNUNET_CURL_job_cancel (gpu->job); + gpu->job = NULL; + } + GNUNET_free (gpu->url); + GNUNET_free (gpu->base_url); + GNUNET_free (gpu->unit_id); + GNUNET_free (gpu); } -/* end of merchant_api_get_unit.c */ +/* end of merchant_api_get-private-units-UNIT-new.c */ diff --git a/src/lib/merchant_api_get-private-units-new.c b/src/lib/merchant_api_get-private-units-new.c @@ -1,345 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-units-new.c - * @brief Implementation of the GET /private/units request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-units-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of units returned in a single response. - */ -#define MAX_UNITS 1024 - - -/** - * Handle for a GET /private/units operation. - */ -struct TALER_MERCHANT_GetPrivateUnitsHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateUnitsCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse an individual unit entry from @a value. - * - * @param value JSON object describing the unit - * @param[out] ue set to the parsed values - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_unit_entry (const json_t *value, - struct TALER_MERCHANT_UnitEntry *ue) -{ - const char *unit; - const char *unit_name_long; - const char *unit_name_short; - const json_t *unit_name_long_i18n = NULL; - const json_t *unit_name_short_i18n = NULL; - bool unit_allow_fraction; - bool unit_active; - bool unit_builtin; - uint32_t unit_precision_level; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("unit", - &unit), - GNUNET_JSON_spec_string ("unit_name_long", - &unit_name_long), - GNUNET_JSON_spec_string ("unit_name_short", - &unit_name_short), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("unit_name_long_i18n", - &unit_name_long_i18n), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("unit_name_short_i18n", - &unit_name_short_i18n), - NULL), - GNUNET_JSON_spec_bool ("unit_allow_fraction", - &unit_allow_fraction), - GNUNET_JSON_spec_uint32 ("unit_precision_level", - &unit_precision_level), - GNUNET_JSON_spec_bool ("unit_active", - &unit_active), - GNUNET_JSON_spec_bool ("unit_builtin", - &unit_builtin), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, - NULL)) - { - GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); - return GNUNET_SYSERR; - } - GNUNET_JSON_parse_free (spec); - ue->unit = unit; - ue->unit_name_long = unit_name_long; - ue->unit_name_short = unit_name_short; - ue->unit_name_long_i18n = unit_name_long_i18n; - ue->unit_name_short_i18n = unit_name_short_i18n; - ue->unit_allow_fraction = unit_allow_fraction; - ue->unit_precision_level = unit_precision_level; - ue->unit_active = unit_active; - ue->unit_builtin = unit_builtin; - return GNUNET_OK; -} - - -/** - * Parse the list of units from @a units and call the callback. - * - * @param json complete response JSON - * @param units array of units - * @param gpuh ongoing operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_units (const json_t *json, - const json_t *units, - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh) -{ - size_t len; - - len = json_array_size (units); - if (len > MAX_UNITS) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - { - struct TALER_MERCHANT_UnitEntry entries[GNUNET_NZL (len)]; - size_t idx; - json_t *value; - - json_array_foreach (units, idx, value) { - if (GNUNET_OK != - parse_unit_entry (value, - &entries[idx])) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - { - struct TALER_MERCHANT_GetPrivateUnitsResponse ugr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details = { - .ok = { - .units = entries, - .units_length = (unsigned int) len - } - - - } - - - }; - - gpuh->cb (gpuh->cb_cls, - &ugr); - } - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/units request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateUnitsHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_units_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateUnitsResponse ugr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpuh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/units response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *units; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("units", - &units), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - ugr.hr.http_status = 0; - ugr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_units (json, - units, - gpuh)) - { - TALER_MERCHANT_get_private_units_cancel (gpuh); - return; - } - ugr.hr.http_status = 0; - ugr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - case MHD_HTTP_FORBIDDEN: - case MHD_HTTP_NOT_FOUND: - case MHD_HTTP_CONFLICT: - ugr.hr.ec = TALER_JSON_get_error_code (json); - ugr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case 0: - ugr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - default: - ugr.hr.ec = TALER_JSON_get_error_code (json); - ugr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unexpected response code %u/%d for GET /private/units\n", - (unsigned int) response_code, - (int) ugr.hr.ec); - break; - } - gpuh->cb (gpuh->cb_cls, - &ugr); - TALER_MERCHANT_get_private_units_cancel (gpuh); -} - - -struct TALER_MERCHANT_GetPrivateUnitsHandle * -TALER_MERCHANT_get_private_units_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh; - - gpuh = GNUNET_new (struct TALER_MERCHANT_GetPrivateUnitsHandle); - gpuh->ctx = ctx; - gpuh->base_url = GNUNET_strdup (url); - return gpuh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_units_start ( - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh, - TALER_MERCHANT_GetPrivateUnitsCallback cb, - TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpuh->cb = cb; - gpuh->cb_cls = cb_cls; - gpuh->url = TALER_url_join (gpuh->base_url, - "private/units", - NULL); - if (NULL == gpuh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpuh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpuh->job = GNUNET_CURL_job_add (gpuh->ctx, - eh, - &handle_get_units_finished, - gpuh); - if (NULL == gpuh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_units_cancel ( - struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh) -{ - if (NULL != gpuh->job) - { - GNUNET_CURL_job_cancel (gpuh->job); - gpuh->job = NULL; - } - GNUNET_free (gpuh->url); - GNUNET_free (gpuh->base_url); - GNUNET_free (gpuh); -} - - -/* end of merchant_api_get-private-units-new.c */ diff --git a/src/lib/merchant_api_get-private-units.c b/src/lib/merchant_api_get-private-units.c @@ -1,32 +1,31 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free - Software Foundation; either version 2.1, or (at your option) any later version. + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - details. + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public License along - with TALER; see the file COPYING.LGPL. If not, see + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-units.c - * @brief Implementation of GET /private/units - * @author Bohdan Potuzhnyi + * @file merchant_api_get-private-units-new.c + * @brief Implementation of the GET /private/units request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-units.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> @@ -40,30 +39,35 @@ /** * Handle for a GET /private/units operation. */ -struct TALER_MERCHANT_UnitsGetHandle +struct TALER_MERCHANT_GetPrivateUnitsHandle { /** - * Fully qualified request URL. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * In-flight job handle. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** - * Callback to invoke with the outcome. + * Function to call with the result. */ - TALER_MERCHANT_UnitsGetCallback cb; + TALER_MERCHANT_GetPrivateUnitsCallback cb; /** - * Closure for @e cb. + * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls; /** - * Execution context. + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; }; @@ -144,13 +148,13 @@ parse_unit_entry (const json_t *value, * * @param json complete response JSON * @param units array of units - * @param ugh ongoing operation handle + * @param gpuh ongoing operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_units (const json_t *json, const json_t *units, - struct TALER_MERCHANT_UnitsGetHandle *ugh) + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh) { size_t len; @@ -176,7 +180,7 @@ parse_units (const json_t *json, } } { - struct TALER_MERCHANT_UnitsGetResponse ugr = { + struct TALER_MERCHANT_GetPrivateUnitsResponse ugr = { .hr.http_status = MHD_HTTP_OK, .hr.reply = json, .details = { @@ -191,8 +195,8 @@ parse_units (const json_t *json, }; - ugh->cb (ugh->cb_cls, - &ugr); + gpuh->cb (gpuh->cb_cls, + &ugr); } } return GNUNET_OK; @@ -200,27 +204,28 @@ parse_units (const json_t *json, /** - * Called when the HTTP transfer finishes. + * Function called when we're done processing the + * HTTP GET /private/units request. * - * @param cls closure, the operation handle - * @param response_code HTTP status (0 on network errors) - * @param response parsed JSON body (NULL if parsing failed) + * @param cls the `struct TALER_MERCHANT_GetPrivateUnitsHandle` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON */ static void handle_get_units_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_UnitsGetHandle *ugh = cls; + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh = cls; const json_t *json = response; - struct TALER_MERCHANT_UnitsGetResponse ugr = { + struct TALER_MERCHANT_GetPrivateUnitsResponse ugr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - ugh->job = NULL; + gpuh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GET /private/units finished with status %u\n", + "Got /private/units response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -236,8 +241,7 @@ handle_get_units_finished (void *cls, if (GNUNET_OK != GNUNET_JSON_parse (json, spec, - NULL, - NULL)) + NULL, NULL)) { GNUNET_break_op (0); ugr.hr.http_status = 0; @@ -247,9 +251,9 @@ handle_get_units_finished (void *cls, if (GNUNET_OK == parse_units (json, units, - ugh)) + gpuh)) { - TALER_MERCHANT_units_get_cancel (ugh); + TALER_MERCHANT_get_private_units_cancel (gpuh); return; } ugr.hr.http_status = 0; @@ -275,55 +279,67 @@ handle_get_units_finished (void *cls, (int) ugr.hr.ec); break; } - ugh->cb (ugh->cb_cls, - &ugr); - TALER_MERCHANT_units_get_cancel (ugh); + gpuh->cb (gpuh->cb_cls, + &ugr); + TALER_MERCHANT_get_private_units_cancel (gpuh); } -struct TALER_MERCHANT_UnitsGetHandle * -TALER_MERCHANT_units_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_UnitsGetCallback cb, - void *cb_cls) +struct TALER_MERCHANT_GetPrivateUnitsHandle * +TALER_MERCHANT_get_private_units_create ( + struct GNUNET_CURL_Context *ctx, + const char *url) +{ + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh; + + gpuh = GNUNET_new (struct TALER_MERCHANT_GetPrivateUnitsHandle); + gpuh->ctx = ctx; + gpuh->base_url = GNUNET_strdup (url); + return gpuh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_units_start ( + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh, + TALER_MERCHANT_GetPrivateUnitsCallback cb, + TALER_MERCHANT_GET_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_UnitsGetHandle *ugh; CURL *eh; - ugh = GNUNET_new (struct TALER_MERCHANT_UnitsGetHandle); - ugh->ctx = ctx; - ugh->cb = cb; - ugh->cb_cls = cb_cls; - ugh->url = TALER_url_join (backend_url, - "private/units", - NULL); - if (NULL == ugh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to build /private/units URL\n"); - GNUNET_free (ugh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - ugh->url); - eh = TALER_MERCHANT_curl_easy_get_ (ugh->url); - ugh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_units_finished, - ugh); - return ugh; + gpuh->cb = cb; + gpuh->cb_cls = cb_cls; + gpuh->url = TALER_url_join (gpuh->base_url, + "private/units", + NULL); + if (NULL == gpuh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpuh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpuh->job = GNUNET_CURL_job_add (gpuh->ctx, + eh, + &handle_get_units_finished, + gpuh); + if (NULL == gpuh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_units_get_cancel (struct TALER_MERCHANT_UnitsGetHandle *ugh) +TALER_MERCHANT_get_private_units_cancel ( + struct TALER_MERCHANT_GetPrivateUnitsHandle *gpuh) { - if (NULL != ugh->job) - GNUNET_CURL_job_cancel (ugh->job); - GNUNET_free (ugh->url); - GNUNET_free (ugh); + if (NULL != gpuh->job) + { + GNUNET_CURL_job_cancel (gpuh->job); + gpuh->job = NULL; + } + GNUNET_free (gpuh->url); + GNUNET_free (gpuh->base_url); + GNUNET_free (gpuh); } -/* end of merchant_api_get_units.c */ +/* end of merchant_api_get-private-units-new.c */ diff --git a/src/lib/merchant_api_get-private-webhooks-WEBHOOK_ID-new.c b/src/lib/merchant_api_get-private-webhooks-WEBHOOK_ID-new.c @@ -1,227 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-webhooks-WEBHOOK_ID-new.c - * @brief Implementation of the GET /private/webhooks/$WEBHOOK_ID request - * @author Priscilla Huang - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /private/webhooks/$WEBHOOK_ID operation. - */ -struct TALER_MERCHANT_GetPrivateWebhookHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateWebhookCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Webhook identifier. - */ - char *webhook_id; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /private/webhooks/$WEBHOOK_ID request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateWebhookHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_webhook_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateWebhookResponse wgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpw->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/webhooks/$WEBHOOK_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("event_type", - &wgr.details.ok.event_type), - TALER_JSON_spec_web_url ("url", - &wgr.details.ok.url), - GNUNET_JSON_spec_string ("http_method", - &wgr.details.ok.http_method), - GNUNET_JSON_spec_string ("header_template", - &wgr.details.ok.header_template), - GNUNET_JSON_spec_string ("body_template", - &wgr.details.ok.body_template), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - gpw->cb (gpw->cb_cls, - &wgr); - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_get_private_webhook_cancel (gpw); - return; - } - wgr.hr.http_status = 0; - wgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - GNUNET_JSON_parse_free (spec); - break; - } - case MHD_HTTP_UNAUTHORIZED: - wgr.hr.ec = TALER_JSON_get_error_code (json); - wgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - case MHD_HTTP_NOT_FOUND: - wgr.hr.ec = TALER_JSON_get_error_code (json); - wgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - /* unexpected response code */ - wgr.hr.ec = TALER_JSON_get_error_code (json); - wgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) wgr.hr.ec); - break; - } - gpw->cb (gpw->cb_cls, - &wgr); - TALER_MERCHANT_get_private_webhook_cancel (gpw); -} - - -struct TALER_MERCHANT_GetPrivateWebhookHandle * -TALER_MERCHANT_get_private_webhook_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id) -{ - struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw; - - gpw = GNUNET_new (struct TALER_MERCHANT_GetPrivateWebhookHandle); - gpw->ctx = ctx; - gpw->base_url = GNUNET_strdup (url); - gpw->webhook_id = GNUNET_strdup (webhook_id); - return gpw; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_webhook_start ( - struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw, - TALER_MERCHANT_GetPrivateWebhookCallback cb, - TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpw->cb = cb; - gpw->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/webhooks/%s", - gpw->webhook_id); - gpw->url = TALER_url_join (gpw->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gpw->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpw->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpw->job = GNUNET_CURL_job_add (gpw->ctx, - eh, - &handle_get_webhook_finished, - gpw); - if (NULL == gpw->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_webhook_cancel ( - struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw) -{ - if (NULL != gpw->job) - { - GNUNET_CURL_job_cancel (gpw->job); - gpw->job = NULL; - } - GNUNET_free (gpw->url); - GNUNET_free (gpw->base_url); - GNUNET_free (gpw->webhook_id); - GNUNET_free (gpw); -} - - -/* end of merchant_api_get-private-webhooks-WEBHOOK_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-webhooks-WEBHOOK_ID.c b/src/lib/merchant_api_get-private-webhooks-WEBHOOK_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,10 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-webhooks-WEBHOOK_ID.c - * @brief Implementation of the GET /webhooks/$ID request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_get-private-webhooks-WEBHOOK_ID-new.c + * @brief Implementation of the GET /private/webhooks/$WEBHOOK_ID request + * @author Priscilla Huang + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +26,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-webhooks-WEBHOOK_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /webhooks/$ID operation. + * Handle for a GET /private/webhooks/$WEBHOOK_ID operation. */ -struct TALER_MERCHANT_WebhookGetHandle +struct TALER_MERCHANT_GetPrivateWebhookHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +54,30 @@ struct TALER_MERCHANT_WebhookGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_WebhookGetCallback cb; + TALER_MERCHANT_GetPrivateWebhookCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Webhook identifier. + */ + char *webhook_id; }; /** * Function called when we're done processing the - * HTTP GET /webhooks/$ID request. + * HTTP GET /private/webhooks/$WEBHOOK_ID request. * - * @param cls the `struct TALER_MERCHANT_WebhookGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateWebhookHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,145 +86,142 @@ handle_get_webhook_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WebhookGetHandle *wgh = cls; + struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_GetPrivateWebhookResponse wgr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - wgh->job = NULL; + gpw->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /webhooks/$ID response with status code %u\n", + "Got /private/webhooks/$WEBHOOK_ID response with status code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_OK: { - const char *event_type; - const char *url; - const char *http_method; - const char *header_template; - const char *body_template; - bool rst_ok = true; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("event_type", - &event_type), + &wgr.details.ok.event_type), TALER_JSON_spec_web_url ("url", - &url), + &wgr.details.ok.url), GNUNET_JSON_spec_string ("http_method", - &http_method), + &wgr.details.ok.http_method), GNUNET_JSON_spec_string ("header_template", - &header_template), + &wgr.details.ok.header_template), GNUNET_JSON_spec_string ("body_template", - &body_template), + &wgr.details.ok.body_template), GNUNET_JSON_spec_end () }; - - if ( (rst_ok) && - (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) ) + if (GNUNET_OK == + GNUNET_JSON_parse (json, + spec, + NULL, NULL)) { - wgh->cb (wgh->cb_cls, - &hr, - event_type, - url, - http_method, - header_template, - body_template); + gpw->cb (gpw->cb_cls, + &wgr); GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_webhook_get_cancel (wgh); + TALER_MERCHANT_get_private_webhook_cancel (gpw); return; } - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wgr.hr.http_status = 0; + wgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; GNUNET_JSON_parse_free (spec); break; } case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wgr.hr.ec = TALER_JSON_get_error_code (json); + wgr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wgr.hr.ec = TALER_JSON_get_error_code (json); + wgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wgr.hr.ec = TALER_JSON_get_error_code (json); + wgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) wgr.hr.ec); break; } - wgh->cb (wgh->cb_cls, - &hr, - NULL, - NULL, - NULL, - NULL, - NULL); - TALER_MERCHANT_webhook_get_cancel (wgh); + gpw->cb (gpw->cb_cls, + &wgr); + TALER_MERCHANT_get_private_webhook_cancel (gpw); } -struct TALER_MERCHANT_WebhookGetHandle * -TALER_MERCHANT_webhook_get ( +struct TALER_MERCHANT_GetPrivateWebhookHandle * +TALER_MERCHANT_get_private_webhook_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *webhook_id, - TALER_MERCHANT_WebhookGetCallback cb, - void *cb_cls) + const char *url, + const char *webhook_id) +{ + struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw; + + gpw = GNUNET_new (struct TALER_MERCHANT_GetPrivateWebhookHandle); + gpw->ctx = ctx; + gpw->base_url = GNUNET_strdup (url); + gpw->webhook_id = GNUNET_strdup (webhook_id); + return gpw; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_webhook_start ( + struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw, + TALER_MERCHANT_GetPrivateWebhookCallback cb, + TALER_MERCHANT_GET_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_WebhookGetHandle *wgh; CURL *eh; - wgh = GNUNET_new (struct TALER_MERCHANT_WebhookGetHandle); - wgh->ctx = ctx; - wgh->cb = cb; - wgh->cb_cls = cb_cls; + gpw->cb = cb; + gpw->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/webhooks/%s", - webhook_id); - wgh->url = TALER_url_join (backend_url, + gpw->webhook_id); + gpw->url = TALER_url_join (gpw->base_url, path, NULL); GNUNET_free (path); } - if (NULL == wgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (wgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - wgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (wgh->url); - wgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gpw->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpw->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpw->job = GNUNET_CURL_job_add (gpw->ctx, eh, &handle_get_webhook_finished, - wgh); - return wgh; + gpw); + if (NULL == gpw->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_webhook_get_cancel ( - struct TALER_MERCHANT_WebhookGetHandle *wgh) +TALER_MERCHANT_get_private_webhook_cancel ( + struct TALER_MERCHANT_GetPrivateWebhookHandle *gpw) { - if (NULL != wgh->job) - GNUNET_CURL_job_cancel (wgh->job); - GNUNET_free (wgh->url); - GNUNET_free (wgh); + if (NULL != gpw->job) + { + GNUNET_CURL_job_cancel (gpw->job); + gpw->job = NULL; + } + GNUNET_free (gpw->url); + GNUNET_free (gpw->base_url); + GNUNET_free (gpw->webhook_id); + GNUNET_free (gpw); } + + +/* end of merchant_api_get-private-webhooks-WEBHOOK_ID-new.c */ diff --git a/src/lib/merchant_api_get-private-webhooks-new.c b/src/lib/merchant_api_get-private-webhooks-new.c @@ -1,265 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-private-webhooks-new.c - * @brief Implementation of the GET /private/webhooks request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-private-webhooks-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Maximum number of webhooks permitted. - */ -#define MAX_WEBHOOKS 1024 - - -/** - * Handle for a GET /private/webhooks operation. - */ -struct TALER_MERCHANT_GetPrivateWebhooksHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetPrivateWebhooksCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; -}; - - -/** - * Parse webhook information from @a ia. - * - * @param ia JSON array (or NULL!) with webhook data - * @param[in] wgr partially filled webhook response - * @param gpwh operation handle - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -parse_webhooks (const json_t *ia, - struct TALER_MERCHANT_GetPrivateWebhooksResponse *wgr, - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh) -{ - unsigned int whook_len = (unsigned int) json_array_size (ia); - - if ( (json_array_size (ia) != (size_t) whook_len) || - (whook_len > MAX_WEBHOOKS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - { - struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry whook[ - GNUNET_NZL (whook_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry *ie = - &whook[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("webhook_id", - &ie->webhook_id), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - wgr->details.ok.webhooks_length = whook_len; - wgr->details.ok.webhooks = whook; - gpwh->cb (gpwh->cb_cls, - wgr); - gpwh->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP GET /private/webhooks request. - * - * @param cls the `struct TALER_MERCHANT_GetPrivateWebhooksHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_webhooks_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetPrivateWebhooksResponse wgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpwh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /private/webhooks response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *webhooks; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("webhooks", - &webhooks), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - wgr.hr.http_status = 0; - wgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - if (GNUNET_OK == - parse_webhooks (webhooks, - &wgr, - gpwh)) - { - TALER_MERCHANT_get_private_webhooks_cancel (gpwh); - return; - } - wgr.hr.http_status = 0; - wgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - wgr.hr.ec = TALER_JSON_get_error_code (json); - wgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - default: - /* unexpected response code */ - wgr.hr.ec = TALER_JSON_get_error_code (json); - wgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) wgr.hr.ec); - break; - } - gpwh->cb (gpwh->cb_cls, - &wgr); - TALER_MERCHANT_get_private_webhooks_cancel (gpwh); -} - - -struct TALER_MERCHANT_GetPrivateWebhooksHandle * -TALER_MERCHANT_get_private_webhooks_create ( - struct GNUNET_CURL_Context *ctx, - const char *url) -{ - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh; - - gpwh = GNUNET_new (struct TALER_MERCHANT_GetPrivateWebhooksHandle); - gpwh->ctx = ctx; - gpwh->base_url = GNUNET_strdup (url); - return gpwh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_private_webhooks_start ( - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh, - TALER_MERCHANT_GetPrivateWebhooksCallback cb, - TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpwh->cb = cb; - gpwh->cb_cls = cb_cls; - gpwh->url = TALER_url_join (gpwh->base_url, - "private/webhooks", - NULL); - if (NULL == gpwh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpwh->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpwh->job = GNUNET_CURL_job_add (gpwh->ctx, - eh, - &handle_get_webhooks_finished, - gpwh); - if (NULL == gpwh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_private_webhooks_cancel ( - struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh) -{ - if (NULL != gpwh->job) - { - GNUNET_CURL_job_cancel (gpwh->job); - gpwh->job = NULL; - } - GNUNET_free (gpwh->url); - GNUNET_free (gpwh->base_url); - GNUNET_free (gpwh); -} - - -/* end of merchant_api_get-private-webhooks-new.c */ diff --git a/src/lib/merchant_api_get-private-webhooks.c b/src/lib/merchant_api_get-private-webhooks.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-private-webhooks.c - * @brief Implementation of the GET /webhooks request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_get-private-webhooks-new.c + * @brief Implementation of the GET /private/webhooks request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,24 +25,29 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-private-webhooks.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Maximum number of webhooks we return. + * Maximum number of webhooks permitted. */ #define MAX_WEBHOOKS 1024 + /** - * Handle for a GET /webhooks operation. + * Handle for a GET /private/webhooks operation. */ -struct TALER_MERCHANT_WebhooksGetHandle +struct TALER_MERCHANT_GetPrivateWebhooksHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -54,18 +59,17 @@ struct TALER_MERCHANT_WebhooksGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_WebhooksGetCallback cb; + TALER_MERCHANT_GetPrivateWebhooksCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; - }; @@ -74,29 +78,31 @@ struct TALER_MERCHANT_WebhooksGetHandle * * @param ia JSON array (or NULL!) with webhook data * @param[in] wgr partially filled webhook response - * @param wgh operation handle + * @param gpwh operation handle * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue parse_webhooks (const json_t *ia, - struct TALER_MERCHANT_WebhooksGetResponse *wgr, - struct TALER_MERCHANT_WebhooksGetHandle *wgh) + struct TALER_MERCHANT_GetPrivateWebhooksResponse *wgr, + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh) { unsigned int whook_len = (unsigned int) json_array_size (ia); - if ( (json_array_size (ia) != (size_t) whook_len) || + if ( (json_array_size (ia) != (size_t) whook_len) || (whook_len > MAX_WEBHOOKS) ) { GNUNET_break (0); return GNUNET_SYSERR; } { - struct TALER_MERCHANT_WebhookEntry whook[GNUNET_NZL (whook_len)]; + struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry whook[ + GNUNET_NZL (whook_len)]; size_t index; json_t *value; json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_WebhookEntry *ie = &whook[index]; + struct TALER_MERCHANT_GetPrivateWebhooksWebhookEntry *ie = + &whook[index]; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("webhook_id", &ie->webhook_id), @@ -114,9 +120,9 @@ parse_webhooks (const json_t *ia, } wgr->details.ok.webhooks_length = whook_len; wgr->details.ok.webhooks = whook; - wgh->cb (wgh->cb_cls, - wgr); - wgh->cb = NULL; /* just to be sure */ + gpwh->cb (gpwh->cb_cls, + wgr); + gpwh->cb = NULL; } return GNUNET_OK; } @@ -124,9 +130,9 @@ parse_webhooks (const json_t *ia, /** * Function called when we're done processing the - * HTTP /webhooks request. + * HTTP GET /private/webhooks request. * - * @param cls the `struct TALER_MERCHANT_WebhooksGetHandle` + * @param cls the `struct TALER_MERCHANT_GetPrivateWebhooksHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -135,16 +141,16 @@ handle_get_webhooks_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WebhooksGetHandle *wgh = cls; + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh = cls; const json_t *json = response; - struct TALER_MERCHANT_WebhooksGetResponse wgr = { + struct TALER_MERCHANT_GetPrivateWebhooksResponse wgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - wgh->job = NULL; + gpwh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /webhooks response with status code %u\n", + "Got /private/webhooks response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -169,9 +175,9 @@ handle_get_webhooks_finished (void *cls, if (GNUNET_OK == parse_webhooks (webhooks, &wgr, - wgh)) + gpwh)) { - TALER_MERCHANT_webhooks_get_cancel (wgh); + TALER_MERCHANT_get_private_webhooks_cancel (gpwh); return; } wgr.hr.http_status = 0; @@ -193,54 +199,67 @@ handle_get_webhooks_finished (void *cls, (int) wgr.hr.ec); break; } - wgh->cb (wgh->cb_cls, - &wgr); - TALER_MERCHANT_webhooks_get_cancel (wgh); + gpwh->cb (gpwh->cb_cls, + &wgr); + TALER_MERCHANT_get_private_webhooks_cancel (gpwh); } -struct TALER_MERCHANT_WebhooksGetHandle * -TALER_MERCHANT_webhooks_get ( +struct TALER_MERCHANT_GetPrivateWebhooksHandle * +TALER_MERCHANT_get_private_webhooks_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - TALER_MERCHANT_WebhooksGetCallback cb, - void *cb_cls) + const char *url) +{ + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh; + + gpwh = GNUNET_new (struct TALER_MERCHANT_GetPrivateWebhooksHandle); + gpwh->ctx = ctx; + gpwh->base_url = GNUNET_strdup (url); + return gpwh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_private_webhooks_start ( + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh, + TALER_MERCHANT_GetPrivateWebhooksCallback cb, + TALER_MERCHANT_GET_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_WebhooksGetHandle *wgh; CURL *eh; - wgh = GNUNET_new (struct TALER_MERCHANT_WebhooksGetHandle); - wgh->ctx = ctx; - wgh->cb = cb; - wgh->cb_cls = cb_cls; - wgh->url = TALER_url_join (backend_url, - "private/webhooks", - NULL); - if (NULL == wgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (wgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - wgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (wgh->url); - wgh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_webhooks_finished, - wgh); - return wgh; + gpwh->cb = cb; + gpwh->cb_cls = cb_cls; + gpwh->url = TALER_url_join (gpwh->base_url, + "private/webhooks", + NULL); + if (NULL == gpwh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpwh->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpwh->job = GNUNET_CURL_job_add (gpwh->ctx, + eh, + &handle_get_webhooks_finished, + gpwh); + if (NULL == gpwh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_webhooks_get_cancel ( - struct TALER_MERCHANT_WebhooksGetHandle *wgh) +TALER_MERCHANT_get_private_webhooks_cancel ( + struct TALER_MERCHANT_GetPrivateWebhooksHandle *gpwh) { - if (NULL != wgh->job) - GNUNET_CURL_job_cancel (wgh->job); - GNUNET_free (wgh->url); - GNUNET_free (wgh); + if (NULL != gpwh->job) + { + GNUNET_CURL_job_cancel (gpwh->job); + gpwh->job = NULL; + } + GNUNET_free (gpwh->url); + GNUNET_free (gpwh->base_url); + GNUNET_free (gpwh); } + + +/* end of merchant_api_get-private-webhooks-new.c */ diff --git a/src/lib/merchant_api_get-products-IMAGE_HASH-image-new.c b/src/lib/merchant_api_get-products-IMAGE_HASH-image-new.c @@ -1,212 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-products-IMAGE_HASH-image-new.c - * @brief Implementation of the GET /products/$IMAGE_HASH/image request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-products-IMAGE_HASH-image-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /products/$IMAGE_HASH/image operation. - */ -struct TALER_MERCHANT_GetProductsImageHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetProductsImageCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Image hash identifier. - */ - char *image_hash; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /products/$IMAGE_HASH/image request. - * - * @param cls the `struct TALER_MERCHANT_GetProductsImageHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_product_image_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetProductsImageHandle *gpi = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetProductsImageResponse pgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gpi->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /products/$IMAGE_HASH/image response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("image", - &pgr.details.ok.image), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - gpi->cb (gpi->cb_cls, - &pgr); - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_get_products_image_cancel (gpi); - return; - } - pgr.hr.http_status = 0; - pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_NOT_FOUND: - case MHD_HTTP_BAD_REQUEST: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - pgr.hr.ec = TALER_JSON_get_error_code (json); - pgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pgr.hr.ec); - break; - } - gpi->cb (gpi->cb_cls, - &pgr); - TALER_MERCHANT_get_products_image_cancel (gpi); -} - - -struct TALER_MERCHANT_GetProductsImageHandle * -TALER_MERCHANT_get_products_image_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *image_hash) -{ - struct TALER_MERCHANT_GetProductsImageHandle *gpi; - - gpi = GNUNET_new (struct TALER_MERCHANT_GetProductsImageHandle); - gpi->ctx = ctx; - gpi->base_url = GNUNET_strdup (url); - gpi->image_hash = GNUNET_strdup (image_hash); - return gpi; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_products_image_start ( - struct TALER_MERCHANT_GetProductsImageHandle *gpi, - TALER_MERCHANT_GetProductsImageCallback cb, - TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gpi->cb = cb; - gpi->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "products/%s/image", - gpi->image_hash); - gpi->url = TALER_url_join (gpi->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gpi->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gpi->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gpi->job = GNUNET_CURL_job_add (gpi->ctx, - eh, - &handle_get_product_image_finished, - gpi); - if (NULL == gpi->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_products_image_cancel ( - struct TALER_MERCHANT_GetProductsImageHandle *gpi) -{ - if (NULL != gpi->job) - { - GNUNET_CURL_job_cancel (gpi->job); - gpi->job = NULL; - } - GNUNET_free (gpi->url); - GNUNET_free (gpi->base_url); - GNUNET_free (gpi->image_hash); - GNUNET_free (gpi); -} - - -/* end of merchant_api_get-products-IMAGE_HASH-image-new.c */ diff --git a/src/lib/merchant_api_get-products-IMAGE_HASH-image.c b/src/lib/merchant_api_get-products-IMAGE_HASH-image.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,29 +15,33 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-products-IMAGE_HASH-image.c - * @brief Implementation of the GET /products/$HASH/image request - * @author Bohdan Potuzhnyi + * @file merchant_api_get-products-IMAGE_HASH-image-new.c + * @brief Implementation of the GET /products/$IMAGE_HASH/image request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include <taler/taler_error_codes.h> -#include <taler/taler_json_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-products-IMAGE_HASH-image.h> #include "merchant_api_curl_defaults.h" +#include <taler/taler_json_lib.h> /** - * Handle for a GET /products/$HASH/image operation. + * Handle for a GET /products/$IMAGE_HASH/image operation. */ -struct TALER_MERCHANT_ProductImageGetHandle +struct TALER_MERCHANT_GetProductsImageHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,25 +53,30 @@ struct TALER_MERCHANT_ProductImageGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductImageGetCallback cb; + TALER_MERCHANT_GetProductsImageCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + + /** + * Image hash identifier. + */ + char *image_hash; }; /** * Function called when we're done processing the - * HTTP GET /products/$HASH/image request. + * HTTP GET /products/$IMAGE_HASH/image request. * - * @param cls the `struct TALER_MERCHANT_ProductImageGetHandle` + * @param cls the `struct TALER_MERCHANT_GetProductsImageHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -76,16 +85,16 @@ handle_get_product_image_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_ProductImageGetHandle *pigh = cls; + struct TALER_MERCHANT_GetProductsImageHandle *gpi = cls; const json_t *json = response; - struct TALER_MERCHANT_ProductImageGetResponse pir = { + struct TALER_MERCHANT_GetProductsImageResponse pgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - pigh->job = NULL; + gpi->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /products/$HASH/image response with status code %u\n", + "Got /products/$IMAGE_HASH/image response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -93,7 +102,7 @@ handle_get_product_image_finished (void *cls, { struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("image", - &pir.details.ok.image), + &pgr.details.ok.image), GNUNET_JSON_spec_end () }; @@ -102,87 +111,102 @@ handle_get_product_image_finished (void *cls, spec, NULL, NULL)) { - pigh->cb (pigh->cb_cls, - &pir); + gpi->cb (gpi->cb_cls, + &pgr); GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_product_image_get_cancel (pigh); + TALER_MERCHANT_get_products_image_cancel (gpi); return; } - pir.hr.http_status = 0; - pir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + pgr.hr.http_status = 0; + pgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_NOT_FOUND: case MHD_HTTP_BAD_REQUEST: - pir.hr.ec = TALER_JSON_get_error_code (json); - pir.hr.hint = TALER_JSON_get_error_hint (json); + pgr.hr.ec = TALER_JSON_get_error_code (json); + pgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - pir.hr.ec = TALER_JSON_get_error_code (json); - pir.hr.hint = TALER_JSON_get_error_hint (json); + pgr.hr.ec = TALER_JSON_get_error_code (json); + pgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) pir.hr.ec); + (int) pgr.hr.ec); break; } - pigh->cb (pigh->cb_cls, - &pir); - TALER_MERCHANT_product_image_get_cancel (pigh); + gpi->cb (gpi->cb_cls, + &pgr); + TALER_MERCHANT_get_products_image_cancel (gpi); } -struct TALER_MERCHANT_ProductImageGetHandle * -TALER_MERCHANT_product_image_get ( +struct TALER_MERCHANT_GetProductsImageHandle * +TALER_MERCHANT_get_products_image_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *image_hash, - TALER_MERCHANT_ProductImageGetCallback cb, - void *cb_cls) + const char *url, + const char *image_hash) +{ + struct TALER_MERCHANT_GetProductsImageHandle *gpi; + + gpi = GNUNET_new (struct TALER_MERCHANT_GetProductsImageHandle); + gpi->ctx = ctx; + gpi->base_url = GNUNET_strdup (url); + gpi->image_hash = GNUNET_strdup (image_hash); + return gpi; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_products_image_start ( + struct TALER_MERCHANT_GetProductsImageHandle *gpi, + TALER_MERCHANT_GetProductsImageCallback cb, + TALER_MERCHANT_GET_PRODUCTS_IMAGE_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ProductImageGetHandle *pigh; CURL *eh; - pigh = GNUNET_new (struct TALER_MERCHANT_ProductImageGetHandle); - pigh->ctx = ctx; - pigh->cb = cb; - pigh->cb_cls = cb_cls; + gpi->cb = cb; + gpi->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "products/%s/image", - image_hash); - pigh->url = TALER_url_join (backend_url, - path, - NULL); + gpi->image_hash); + gpi->url = TALER_url_join (gpi->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == pigh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (pigh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - pigh->url); - eh = TALER_MERCHANT_curl_easy_get_ (pigh->url); - pigh->job = GNUNET_CURL_job_add (ctx, - eh, - &handle_get_product_image_finished, - pigh); - return pigh; + if (NULL == gpi->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gpi->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gpi->job = GNUNET_CURL_job_add (gpi->ctx, + eh, + &handle_get_product_image_finished, + gpi); + if (NULL == gpi->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_product_image_get_cancel ( - struct TALER_MERCHANT_ProductImageGetHandle *pigh) +TALER_MERCHANT_get_products_image_cancel ( + struct TALER_MERCHANT_GetProductsImageHandle *gpi) { - if (NULL != pigh->job) - GNUNET_CURL_job_cancel (pigh->job); - GNUNET_free (pigh->url); - GNUNET_free (pigh); -} -\ No newline at end of file + if (NULL != gpi->job) + { + GNUNET_CURL_job_cancel (gpi->job); + gpi->job = NULL; + } + GNUNET_free (gpi->url); + GNUNET_free (gpi->base_url); + GNUNET_free (gpi->image_hash); + GNUNET_free (gpi); +} + + +/* end of merchant_api_get-products-IMAGE_HASH-image-new.c */ diff --git a/src/lib/merchant_api_get-templates-TEMPLATE_ID-new.c b/src/lib/merchant_api_get-templates-TEMPLATE_ID-new.c @@ -1,216 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_get-templates-TEMPLATE_ID-new.c - * @brief Implementation of the GET /templates/$TEMPLATE_ID request (wallet-facing) - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/get-templates-TEMPLATE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include <taler/taler_json_lib.h> - - -/** - * Handle for a GET /templates/$TEMPLATE_ID operation (wallet-facing). - */ -struct TALER_MERCHANT_GetTemplatesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_GetTemplatesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Template identifier. - */ - char *template_id; -}; - - -/** - * Function called when we're done processing the - * HTTP GET /templates/$TEMPLATE_ID request. - * - * @param cls the `struct TALER_MERCHANT_GetTemplatesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_get_template_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_GetTemplatesHandle *gth = cls; - const json_t *json = response; - struct TALER_MERCHANT_GetTemplatesResponse wtgr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - gth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /templates/$TEMPLATE_ID response with status code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - { - const json_t *contract; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_object_const ("template_contract", - &contract), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK == - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - wtgr.details.ok.template_contract = contract; - gth->cb (gth->cb_cls, - &wtgr); - TALER_MERCHANT_get_templates_cancel (gth); - return; - } - wtgr.hr.http_status = 0; - wtgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - case MHD_HTTP_UNAUTHORIZED: - wtgr.hr.ec = TALER_JSON_get_error_code (json); - wtgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - wtgr.hr.ec = TALER_JSON_get_error_code (json); - wtgr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - wtgr.hr.ec = TALER_JSON_get_error_code (json); - wtgr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) wtgr.hr.ec); - break; - } - gth->cb (gth->cb_cls, - &wtgr); - TALER_MERCHANT_get_templates_cancel (gth); -} - - -struct TALER_MERCHANT_GetTemplatesHandle * -TALER_MERCHANT_get_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id) -{ - struct TALER_MERCHANT_GetTemplatesHandle *gth; - - gth = GNUNET_new (struct TALER_MERCHANT_GetTemplatesHandle); - gth->ctx = ctx; - gth->base_url = GNUNET_strdup (url); - gth->template_id = GNUNET_strdup (template_id); - return gth; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_get_templates_start ( - struct TALER_MERCHANT_GetTemplatesHandle *gth, - TALER_MERCHANT_GetTemplatesCallback cb, - TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cb_cls) -{ - CURL *eh; - - gth->cb = cb; - gth->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "templates/%s", - gth->template_id); - gth->url = TALER_url_join (gth->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == gth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - eh = TALER_MERCHANT_curl_easy_get_ (gth->url); - if (NULL == eh) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - gth->job = GNUNET_CURL_job_add (gth->ctx, - eh, - &handle_get_template_finished, - gth); - if (NULL == gth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_get_templates_cancel ( - struct TALER_MERCHANT_GetTemplatesHandle *gth) -{ - if (NULL != gth->job) - { - GNUNET_CURL_job_cancel (gth->job); - gth->job = NULL; - } - GNUNET_free (gth->url); - GNUNET_free (gth->base_url); - GNUNET_free (gth->template_id); - GNUNET_free (gth); -} - - -/* end of merchant_api_get-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_get-templates-TEMPLATE_ID.c b/src/lib/merchant_api_get-templates-TEMPLATE_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_get-templates-TEMPLATE_ID.c - * @brief Implementation of the GET /templates/$ID request of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_get-templates-TEMPLATE_ID-new.c + * @brief Implementation of the GET /templates/$TEMPLATE_ID request (wallet-facing) + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,19 +25,23 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/get-templates-TEMPLATE_ID.h> #include "merchant_api_curl_defaults.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> /** - * Handle for a GET /templates/$ID operation. + * Handle for a GET /templates/$TEMPLATE_ID operation (wallet-facing). */ -struct TALER_MERCHANT_WalletTemplateGetHandle +struct TALER_MERCHANT_GetTemplatesHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -49,26 +53,30 @@ struct TALER_MERCHANT_WalletTemplateGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_WalletTemplateGetCallback cb; + TALER_MERCHANT_GetTemplatesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; + /** + * Template identifier. + */ + char *template_id; }; /** * Function called when we're done processing the - * HTTP GET /templates/$ID request. + * HTTP GET /templates/$TEMPLATE_ID request. * - * @param cls the `struct TALER_MERCHANT_TemplateGetHandle` + * @param cls the `struct TALER_MERCHANT_GetTemplatesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -77,16 +85,16 @@ handle_get_template_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WalletTemplateGetHandle *tgh = cls; + struct TALER_MERCHANT_GetTemplatesHandle *gth = cls; const json_t *json = response; - struct TALER_MERCHANT_WalletTemplateGetResponse tgr = { + struct TALER_MERCHANT_GetTemplatesResponse wtgr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - tgh->job = NULL; + gth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /templates/$ID response with status code %u\n", + "Got /templates/$TEMPLATE_ID response with status code %u\n", (unsigned int) response_code); switch (response_code) { @@ -104,92 +112,105 @@ handle_get_template_finished (void *cls, spec, NULL, NULL)) { - tgr.details.ok.template_contract = contract; - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_wallet_template_get_cancel (tgh); + wtgr.details.ok.template_contract = contract; + gth->cb (gth->cb_cls, + &wtgr); + TALER_MERCHANT_get_templates_cancel (gth); return; } - tgr.hr.http_status = 0; - tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wtgr.hr.http_status = 0; + wtgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + wtgr.hr.ec = TALER_JSON_get_error_code (json); + wtgr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + wtgr.hr.ec = TALER_JSON_get_error_code (json); + wtgr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - tgr.hr.ec = TALER_JSON_get_error_code (json); - tgr.hr.hint = TALER_JSON_get_error_hint (json); + wtgr.hr.ec = TALER_JSON_get_error_code (json); + wtgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) tgr.hr.ec); + (int) wtgr.hr.ec); break; } - tgh->cb (tgh->cb_cls, - &tgr); - TALER_MERCHANT_wallet_template_get_cancel (tgh); + gth->cb (gth->cb_cls, + &wtgr); + TALER_MERCHANT_get_templates_cancel (gth); } -struct TALER_MERCHANT_WalletTemplateGetHandle * -TALER_MERCHANT_wallet_template_get ( +struct TALER_MERCHANT_GetTemplatesHandle * +TALER_MERCHANT_get_templates_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - TALER_MERCHANT_WalletTemplateGetCallback cb, - void *cb_cls) + const char *url, + const char *template_id) +{ + struct TALER_MERCHANT_GetTemplatesHandle *gth; + + gth = GNUNET_new (struct TALER_MERCHANT_GetTemplatesHandle); + gth->ctx = ctx; + gth->base_url = GNUNET_strdup (url); + gth->template_id = GNUNET_strdup (template_id); + return gth; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_get_templates_start ( + struct TALER_MERCHANT_GetTemplatesHandle *gth, + TALER_MERCHANT_GetTemplatesCallback cb, + TALER_MERCHANT_GET_TEMPLATES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_WalletTemplateGetHandle *tgh; CURL *eh; - tgh = GNUNET_new (struct TALER_MERCHANT_WalletTemplateGetHandle); - tgh->ctx = ctx; - tgh->cb = cb; - tgh->cb_cls = cb_cls; + gth->cb = cb; + gth->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "templates/%s", - template_id); - tgh->url = TALER_url_join (backend_url, + gth->template_id); + gth->url = TALER_url_join (gth->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tgh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (tgh); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - tgh->url); - eh = TALER_MERCHANT_curl_easy_get_ (tgh->url); - tgh->job = GNUNET_CURL_job_add (ctx, + if (NULL == gth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + eh = TALER_MERCHANT_curl_easy_get_ (gth->url); + if (NULL == eh) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + gth->job = GNUNET_CURL_job_add (gth->ctx, eh, &handle_get_template_finished, - tgh); - return tgh; + gth); + if (NULL == gth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_wallet_template_get_cancel ( - struct TALER_MERCHANT_WalletTemplateGetHandle *tgh) +TALER_MERCHANT_get_templates_cancel ( + struct TALER_MERCHANT_GetTemplatesHandle *gth) { - if (NULL != tgh->job) - GNUNET_CURL_job_cancel (tgh->job); - GNUNET_free (tgh->url); - GNUNET_free (tgh); + if (NULL != gth->job) + { + GNUNET_CURL_job_cancel (gth->job); + gth->job = NULL; + } + GNUNET_free (gth->url); + GNUNET_free (gth->base_url); + GNUNET_free (gth->template_id); + GNUNET_free (gth); } + + +/* end of merchant_api_get-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_patch-management-instances-INSTANCE-new.c b/src/lib/merchant_api_patch-management-instances-INSTANCE-new.c @@ -1,313 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-management-instances-INSTANCE-new.c - * @brief Implementation of the PATCH /management/instances/$INSTANCE request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-management-instances-INSTANCE-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /management/instances/$INSTANCE operation. - */ -struct TALER_MERCHANT_PatchManagementInstancesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchManagementInstancesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Instance identifier. - */ - char *instance_id; - - /** - * Human-readable name for the instance. - */ - char *name; - - /** - * Address (JSON). - */ - json_t *address; - - /** - * Jurisdiction (JSON). - */ - json_t *jurisdiction; - - /** - * Whether to use STEFAN curves for fee calculations. - */ - bool use_stefan; - - /** - * Default wire transfer delay. - */ - struct GNUNET_TIME_Relative default_wire_transfer_delay; - - /** - * Default payment deadline. - */ - struct GNUNET_TIME_Relative default_pay_delay; - - /** - * Default refund deadline. - */ - struct GNUNET_TIME_Relative default_refund_delay; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /management/instances/$INSTANCE request. - * - * @param cls the `struct TALER_MERCHANT_PatchManagementInstancesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_management_instances_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchManagementInstancesResponse pmir = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - pmih->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /management/instances/$INSTANCE completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - pmir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - pmir.hr.ec = TALER_JSON_get_error_code (json); - pmir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - pmir.hr.ec = TALER_JSON_get_error_code (json); - pmir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - pmir.hr.ec = TALER_JSON_get_error_code (json); - pmir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - pmir.hr.ec = TALER_JSON_get_error_code (json); - pmir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - pmir.hr.ec = TALER_JSON_get_error_code (json); - pmir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - pmir.hr.ec = TALER_JSON_get_error_code (json); - pmir.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pmir.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pmir.hr.ec); - GNUNET_break_op (0); - break; - } - pmih->cb (pmih->cb_cls, - &pmir); - TALER_MERCHANT_patch_management_instances_cancel (pmih); -} - - -struct TALER_MERCHANT_PatchManagementInstancesHandle * -TALER_MERCHANT_patch_management_instances_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - 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) -{ - struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih; - - pmih = GNUNET_new (struct TALER_MERCHANT_PatchManagementInstancesHandle); - pmih->ctx = ctx; - pmih->base_url = GNUNET_strdup (url); - pmih->instance_id = GNUNET_strdup (instance_id); - pmih->name = GNUNET_strdup (name); - 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 TALER_ErrorCode -TALER_MERCHANT_patch_management_instances_start ( - struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih, - TALER_MERCHANT_PatchManagementInstancesCallback cb, - TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - pmih->cb = cb; - pmih->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "management/instances/%s", - pmih->instance_id); - pmih->url = TALER_url_join (pmih->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == pmih->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("name", - pmih->name), - GNUNET_JSON_pack_object_incref ("address", - pmih->address), - GNUNET_JSON_pack_object_incref ("jurisdiction", - 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) - ); - eh = TALER_MERCHANT_curl_easy_get_ (pmih->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pmih->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - pmih->job = GNUNET_CURL_job_add2 (pmih->ctx, - eh, - pmih->post_ctx.headers, - &handle_patch_management_instances_finished, - pmih); - if (NULL == pmih->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_management_instances_cancel ( - struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih) -{ - if (NULL != pmih->job) - { - GNUNET_CURL_job_cancel (pmih->job); - pmih->job = NULL; - } - TALER_curl_easy_post_finished (&pmih->post_ctx); - json_decref (pmih->address); - json_decref (pmih->jurisdiction); - GNUNET_free (pmih->instance_id); - GNUNET_free (pmih->name); - GNUNET_free (pmih->url); - GNUNET_free (pmih->base_url); - GNUNET_free (pmih); -} - - -/* end of merchant_api_patch-management-instances-INSTANCE-new.c */ diff --git a/src/lib/merchant_api_patch-management-instances-INSTANCE.c b/src/lib/merchant_api_patch-management-instances-INSTANCE.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-management-instances-INSTANCE.c - * @brief Implementation of the PATCH /instances/$ID request - * of the merchant's HTTP API + * @file merchant_api_patch-management-instances-INSTANCE-new.c + * @brief Implementation of the PATCH /management/instances/$INSTANCE request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,22 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-management-instances-INSTANCE.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_kyclogic_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a PATCH /instances/$ID operation. + * Handle for a PATCH /management/instances/$INSTANCE operation. */ -struct TALER_MERCHANT_InstancePatchHandle +struct TALER_MERCHANT_PatchManagementInstancesHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -54,12 +57,12 @@ struct TALER_MERCHANT_InstancePatchHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstancePatchCallback cb; + TALER_MERCHANT_PatchManagementInstancesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -71,92 +74,124 @@ struct TALER_MERCHANT_InstancePatchHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Instance identifier. + */ + char *instance_id; + + /** + * Human-readable name for the instance. + */ + char *name; + + /** + * Address (JSON). + */ + json_t *address; + + /** + * Jurisdiction (JSON). + */ + json_t *jurisdiction; + + /** + * Whether to use STEFAN curves for fee calculations. + */ + bool use_stefan; + + /** + * Default wire transfer delay. + */ + struct GNUNET_TIME_Relative default_wire_transfer_delay; + + /** + * Default payment deadline. + */ + struct GNUNET_TIME_Relative default_pay_delay; + + /** + * Default refund deadline. + */ + struct GNUNET_TIME_Relative default_refund_delay; }; /** * Function called when we're done processing the - * HTTP PATCH /instances/$ID request. + * HTTP PATCH /management/instances/$INSTANCE request. * - * @param cls the `struct TALER_MERCHANT_InstancePatchHandle` + * @param cls the `struct TALER_MERCHANT_PatchManagementInstancesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_patch_instance_finished (void *cls, - long response_code, - const void *response) +handle_patch_management_instances_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_InstancePatchHandle *iph = cls; + struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchManagementInstancesResponse pmir = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - iph->job = NULL; + pmih->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /instances/$ID completed with response code %u\n", + "PATCH /management/instances/$INSTANCE completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + pmir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pmir.hr.ec = TALER_JSON_get_error_code (json); + pmir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + pmir.hr.ec = TALER_JSON_get_error_code (json); + pmir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + pmir.hr.ec = TALER_JSON_get_error_code (json); + pmir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pmir.hr.ec = TALER_JSON_get_error_code (json); + pmir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + pmir.hr.ec = TALER_JSON_get_error_code (json); + pmir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + pmir.hr.ec = TALER_JSON_get_error_code (json); + pmir.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &pmir.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) pmir.hr.ec); GNUNET_break_op (0); break; } - iph->cb (iph->cb_cls, - &hr); - TALER_MERCHANT_instance_patch_cancel (iph); + pmih->cb (pmih->cb_cls, + &pmir); + TALER_MERCHANT_patch_management_instances_cancel (pmih); } -struct TALER_MERCHANT_InstancePatchHandle * -TALER_MERCHANT_instance_patch ( +struct TALER_MERCHANT_PatchManagementInstancesHandle * +TALER_MERCHANT_patch_management_instances_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, const char *name, const json_t *address, @@ -164,108 +199,115 @@ TALER_MERCHANT_instance_patch ( 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, - TALER_MERCHANT_InstancePatchCallback cb, - void *cb_cls) + struct GNUNET_TIME_Relative default_refund_delay) +{ + struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih; + + pmih = GNUNET_new (struct TALER_MERCHANT_PatchManagementInstancesHandle); + pmih->ctx = ctx; + pmih->base_url = GNUNET_strdup (url); + pmih->instance_id = GNUNET_strdup (instance_id); + pmih->name = GNUNET_strdup (name); + 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 TALER_ErrorCode +TALER_MERCHANT_patch_management_instances_start ( + struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih, + TALER_MERCHANT_PatchManagementInstancesCallback cb, + TALER_MERCHANT_PATCH_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_InstancePatchHandle *iph; json_t *req_obj; + CURL *eh; + pmih->cb = cb; + pmih->cb_cls = cb_cls; + { + char *path; + + GNUNET_asprintf (&path, + "management/instances/%s", + pmih->instance_id); + pmih->url = TALER_url_join (pmih->base_url, + path, + NULL); + GNUNET_free (path); + } + if (NULL == pmih->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("name", - name), + pmih->name), GNUNET_JSON_pack_object_incref ("address", - (json_t *) address), + pmih->address), GNUNET_JSON_pack_object_incref ("jurisdiction", - (json_t *) jurisdiction), + pmih->jurisdiction), GNUNET_JSON_pack_bool ("use_stefan", - use_stefan), + pmih->use_stefan), GNUNET_JSON_pack_time_rel ("default_wire_transfer_delay", - default_wire_transfer_delay), + pmih->default_wire_transfer_delay), GNUNET_JSON_pack_time_rel ("default_pay_delay", - default_pay_delay), + pmih->default_pay_delay), GNUNET_JSON_pack_time_rel ("default_refund_delay", - default_refund_delay), - /* FIXME: add eventually to arguments when we transform the API... */ + pmih->default_refund_delay), GNUNET_JSON_pack_time_rounder_interval ( "default_wire_transfer_rounding_interval", GNUNET_TIME_RI_NONE) ); - iph = GNUNET_new (struct TALER_MERCHANT_InstancePatchHandle); - iph->ctx = ctx; - iph->cb = cb; - iph->cb_cls = cb_cls; - if (NULL != instance_id) - { - char *path; - - GNUNET_asprintf (&path, - "management/instances/%s", - instance_id); - iph->url = TALER_url_join (backend_url, - path, - NULL); - GNUNET_free (path); - } - else - { - /* backend_url is already identifying the instance */ - iph->url = TALER_url_join (backend_url, - "private", - NULL); - } - if (NULL == iph->url) + eh = TALER_MERCHANT_curl_easy_get_ (pmih->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pmih->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (iph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (iph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&iph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (iph->url); - GNUNET_free (iph); - return NULL; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - iph->job = GNUNET_CURL_job_add2 (ctx, - eh, - iph->post_ctx.headers, - &handle_patch_instance_finished, - iph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return iph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + pmih->job = GNUNET_CURL_job_add2 (pmih->ctx, + eh, + pmih->post_ctx.headers, + &handle_patch_management_instances_finished, + pmih); + if (NULL == pmih->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instance_patch_cancel ( - struct TALER_MERCHANT_InstancePatchHandle *iph) +TALER_MERCHANT_patch_management_instances_cancel ( + struct TALER_MERCHANT_PatchManagementInstancesHandle *pmih) { - if (NULL != iph->job) + if (NULL != pmih->job) { - GNUNET_CURL_job_cancel (iph->job); - iph->job = NULL; + GNUNET_CURL_job_cancel (pmih->job); + pmih->job = NULL; } - TALER_curl_easy_post_finished (&iph->post_ctx); - GNUNET_free (iph->url); - GNUNET_free (iph); + TALER_curl_easy_post_finished (&pmih->post_ctx); + json_decref (pmih->address); + json_decref (pmih->jurisdiction); + GNUNET_free (pmih->instance_id); + GNUNET_free (pmih->name); + GNUNET_free (pmih->url); + GNUNET_free (pmih->base_url); + GNUNET_free (pmih); } -/* end of merchant_api_patch_instance.c */ +/* end of merchant_api_patch-management-instances-INSTANCE-new.c */ diff --git a/src/lib/merchant_api_patch-private-accounts-H_WIRE-new.c b/src/lib/merchant_api_patch-private-accounts-H_WIRE-new.c @@ -1,295 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-accounts-H_WIRE-new.c - * @brief Implementation of the PATCH /private/accounts/$H_WIRE request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-accounts-H_WIRE-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/accounts/$H_WIRE operation. - */ -struct TALER_MERCHANT_PatchPrivateAccountHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateAccountCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Hash of the wire details identifying the account. - */ - struct TALER_MerchantWireHashP h_wire; - - /** - * Optional credit facade URL. - */ - const char *credit_facade_url; - - /** - * Optional credit facade credentials (JSON). - */ - const json_t *credit_facade_credentials; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/accounts/$H_WIRE request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateAccountHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_account_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateAccountResponse par = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - pah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/accounts/$H_WIRE completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - par.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - par.hr.ec = TALER_JSON_get_error_code (json); - par.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_break_op (0); - break; - case MHD_HTTP_UNAUTHORIZED: - par.hr.ec = TALER_JSON_get_error_code (json); - par.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - par.hr.ec = TALER_JSON_get_error_code (json); - par.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - par.hr.ec = TALER_JSON_get_error_code (json); - par.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - par.hr.ec = TALER_JSON_get_error_code (json); - par.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - par.hr.ec = TALER_JSON_get_error_code (json); - par.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &par.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) par.hr.ec); - GNUNET_break_op (0); - break; - } - pah->cb (pah->cb_cls, - &par); - TALER_MERCHANT_patch_private_account_cancel (pah); -} - - -struct TALER_MERCHANT_PatchPrivateAccountHandle * -TALER_MERCHANT_patch_private_account_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_MerchantWireHashP *h_wire) -{ - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah; - - pah = GNUNET_new (struct TALER_MERCHANT_PatchPrivateAccountHandle); - pah->ctx = ctx; - pah->base_url = GNUNET_strdup (url); - pah->h_wire = *h_wire; - return pah; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_patch_private_account_set_options_ ( - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, - unsigned int num_options, - const struct TALER_MERCHANT_PatchPrivateAccountOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - 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; - break; - case TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS: - pah->credit_facade_credentials - = options[i].details.credit_facade_credentials; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_account_start ( - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, - TALER_MERCHANT_PatchPrivateAccountCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - pah->cb = cb; - pah->cb_cls = cb_cls; - { - char w_str[sizeof (pah->h_wire) * 2]; - char *path; - char *end; - - end = GNUNET_STRINGS_data_to_string (&pah->h_wire, - sizeof (pah->h_wire), - w_str, - sizeof (w_str)); - *end = '\0'; - GNUNET_asprintf (&path, - "private/accounts/%s", - w_str); - pah->url = TALER_url_join (pah->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == pah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("credit_facade_url", - pah->credit_facade_url)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("credit_facade_credentials", - (json_t *) pah->credit_facade_credentials) - )); - eh = TALER_MERCHANT_curl_easy_get_ (pah->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pah->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - pah->job = GNUNET_CURL_job_add2 (pah->ctx, - eh, - pah->post_ctx.headers, - &handle_patch_account_finished, - pah); - if (NULL == pah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_account_cancel ( - struct TALER_MERCHANT_PatchPrivateAccountHandle *pah) -{ - if (NULL != pah->job) - { - GNUNET_CURL_job_cancel (pah->job); - pah->job = NULL; - } - TALER_curl_easy_post_finished (&pah->post_ctx); - GNUNET_free (pah->url); - GNUNET_free (pah->base_url); - GNUNET_free (pah); -} - - -/* end of merchant_api_patch-private-accounts-H_WIRE-new.c */ diff --git a/src/lib/merchant_api_patch-private-accounts-H_WIRE.c b/src/lib/merchant_api_patch-private-accounts-H_WIRE.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,31 +17,35 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-accounts-H_WIRE.c - * @brief Implementation of the PATCH /accounts/$ID request - * of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_patch-private-accounts-H_WIRE-new.c + * @brief Implementation of the PATCH /private/accounts/$H_WIRE request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-accounts-H_WIRE.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a PATCH /accounts/$ID operation. + * Handle for a PATCH /private/accounts/$H_WIRE operation. */ -struct TALER_MERCHANT_AccountPatchHandle +struct TALER_MERCHANT_PatchPrivateAccountHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_AccountPatchHandle /** * Function to call with the result. */ - TALER_MERCHANT_AccountPatchCallback cb; + TALER_MERCHANT_PatchPrivateAccountCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,28 @@ struct TALER_MERCHANT_AccountPatchHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Hash of the wire details identifying the account. + */ + struct TALER_MerchantWireHashP h_wire; + + /** + * Optional credit facade URL. + */ + const char *credit_facade_url; + + /** + * Optional credit facade credentials (JSON). + */ + const json_t *credit_facade_credentials; }; /** * Function called when we're done processing the - * HTTP PATCH /accounts/$ID request. + * HTTP PATCH /private/accounts/$H_WIRE request. * - * @param cls the `struct TALER_MERCHANT_AccountPatchHandle` + * @param cls the `struct TALER_MERCHANT_PatchPrivateAccountHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,169 +104,192 @@ handle_patch_account_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_AccountPatchHandle *tph = cls; + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateAccountResponse par = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tph->job = NULL; + pah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /accounts/$ID completed with response code %u\n", + "PATCH /private/accounts/$H_WIRE completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + par.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + par.hr.ec = TALER_JSON_get_error_code (json); + par.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break_op (0); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + par.hr.ec = TALER_JSON_get_error_code (json); + par.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + par.hr.ec = TALER_JSON_get_error_code (json); + par.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + par.hr.ec = TALER_JSON_get_error_code (json); + par.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + par.hr.ec = TALER_JSON_get_error_code (json); + par.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + par.hr.ec = TALER_JSON_get_error_code (json); + par.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &par.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) par.hr.ec); GNUNET_break_op (0); break; } - tph->cb (tph->cb_cls, - &hr); - TALER_MERCHANT_account_patch_cancel (tph); + pah->cb (pah->cb_cls, + &par); + TALER_MERCHANT_patch_private_account_cancel (pah); } -struct TALER_MERCHANT_AccountPatchHandle * -TALER_MERCHANT_account_patch ( +struct TALER_MERCHANT_PatchPrivateAccountHandle * +TALER_MERCHANT_patch_private_account_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MerchantWireHashP *h_wire, - const char *credit_facade_url, - const json_t *credit_facade_credentials, - TALER_MERCHANT_AccountPatchCallback cb, - void *cb_cls) + const char *url, + const struct TALER_MerchantWireHashP *h_wire) +{ + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah; + + pah = GNUNET_new (struct TALER_MERCHANT_PatchPrivateAccountHandle); + pah->ctx = ctx; + pah->base_url = GNUNET_strdup (url); + pah->h_wire = *h_wire; + return pah; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_account_set_options_ ( + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateAccountOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + 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; + break; + case TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_OPTION_CREDIT_FACADE_CREDENTIALS: + pah->credit_facade_credentials + = options[i].details.credit_facade_credentials; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_account_start ( + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah, + TALER_MERCHANT_PatchPrivateAccountCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_AccountPatchHandle *tph; json_t *req_obj; + CURL *eh; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("credit_facade_url", - credit_facade_url)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("credit_facade_credentials", - (json_t *) credit_facade_credentials))); - tph = GNUNET_new (struct TALER_MERCHANT_AccountPatchHandle); - tph->ctx = ctx; - tph->cb = cb; - tph->cb_cls = cb_cls; + pah->cb = cb; + pah->cb_cls = cb_cls; { - char w_str[sizeof (*h_wire) * 2]; + char w_str[sizeof (pah->h_wire) * 2]; char *path; char *end; - end = GNUNET_STRINGS_data_to_string (h_wire, - sizeof (*h_wire), + end = GNUNET_STRINGS_data_to_string (&pah->h_wire, + sizeof (pah->h_wire), w_str, sizeof (w_str)); *end = '\0'; GNUNET_asprintf (&path, "private/accounts/%s", w_str); - tph->url = TALER_url_join (backend_url, + pah->url = TALER_url_join (pah->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tph->url) + if (NULL == pah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("credit_facade_url", + pah->credit_facade_url)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("credit_facade_credentials", + (json_t *) pah->credit_facade_credentials) + )); + eh = TALER_MERCHANT_curl_easy_get_ (pah->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pah->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&tph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - tph->job = GNUNET_CURL_job_add2 (ctx, - eh, - tph->post_ctx.headers, - &handle_patch_account_finished, - tph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return tph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + pah->job = GNUNET_CURL_job_add2 (pah->ctx, + eh, + pah->post_ctx.headers, + &handle_patch_account_finished, + pah); + if (NULL == pah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_account_patch_cancel ( - struct TALER_MERCHANT_AccountPatchHandle *tph) +TALER_MERCHANT_patch_private_account_cancel ( + struct TALER_MERCHANT_PatchPrivateAccountHandle *pah) { - if (NULL != tph->job) + if (NULL != pah->job) { - GNUNET_CURL_job_cancel (tph->job); - tph->job = NULL; + GNUNET_CURL_job_cancel (pah->job); + pah->job = NULL; } - TALER_curl_easy_post_finished (&tph->post_ctx); - GNUNET_free (tph->url); - GNUNET_free (tph); + TALER_curl_easy_post_finished (&pah->post_ctx); + GNUNET_free (pah->url); + GNUNET_free (pah->base_url); + GNUNET_free (pah); } -/* end of merchant_api_patch_account.c */ +/* end of merchant_api_patch-private-accounts-H_WIRE-new.c */ diff --git a/src/lib/merchant_api_patch-private-orders-ORDER_ID-forget-new.c b/src/lib/merchant_api_patch-private-orders-ORDER_ID-forget-new.c @@ -1,279 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-orders-ORDER_ID-forget-new.c - * @brief Implementation of the PATCH /private/orders/$ORDER_ID/forget request - * @author Jonathan Buchanan - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/orders/$ORDER_ID/forget operation. - */ -struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateOrdersForgetCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order identifier. - */ - char *order_id; - - /** - * Array of JSON pointer paths to redact. - */ - char **fields; - - /** - * Number of entries in @e fields. - */ - unsigned int fields_length; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/orders/$ORDER_ID/forget request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_orders_forget_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateOrdersForgetResponse por = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ofh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/orders/$ORDER_ID/forget completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - por.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - /* fields were NOW forgotten */ - break; - case MHD_HTTP_NO_CONTENT: - /* fields were already forgotten before */ - break; - case MHD_HTTP_BAD_REQUEST: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &por.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) por.hr.ec); - GNUNET_break_op (0); - break; - } - ofh->cb (ofh->cb_cls, - &por); - TALER_MERCHANT_patch_private_orders_forget_cancel (ofh); -} - - -struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle * -TALER_MERCHANT_patch_private_orders_forget_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - unsigned int fields_length, - const char *fields[static fields_length]) -{ - struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh; - - ofh = GNUNET_new (struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle); - ofh->ctx = ctx; - ofh->base_url = GNUNET_strdup (url); - ofh->order_id = GNUNET_strdup (order_id); - ofh->fields_length = fields_length; - ofh->fields = GNUNET_new_array (fields_length, - char *); - for (unsigned int i = 0; i < fields_length; i++) - ofh->fields[i] = GNUNET_strdup (fields[i]); - return ofh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_orders_forget_start ( - struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh, - TALER_MERCHANT_PatchPrivateOrdersForgetCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cb_cls) -{ - json_t *req_fields; - json_t *req_obj; - CURL *eh; - - ofh->cb = cb; - ofh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/orders/%s/forget", - ofh->order_id); - ofh->url = TALER_url_join (ofh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == ofh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_fields = json_array (); - if (NULL == req_fields) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - for (unsigned int i = 0; i < ofh->fields_length; i++) - { - if (0 != - json_array_append_new (req_fields, - json_string (ofh->fields[i]))) - { - json_decref (req_fields); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("fields", - req_fields)); - eh = TALER_MERCHANT_curl_easy_get_ (ofh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ofh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - ofh->job = GNUNET_CURL_job_add2 (ofh->ctx, - eh, - ofh->post_ctx.headers, - &handle_patch_orders_forget_finished, - ofh); - if (NULL == ofh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_orders_forget_cancel ( - struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh) -{ - if (NULL != ofh->job) - { - GNUNET_CURL_job_cancel (ofh->job); - ofh->job = NULL; - } - TALER_curl_easy_post_finished (&ofh->post_ctx); - for (unsigned int i = 0; i < ofh->fields_length; i++) - GNUNET_free (ofh->fields[i]); - GNUNET_free (ofh->fields); - GNUNET_free (ofh->order_id); - GNUNET_free (ofh->url); - GNUNET_free (ofh->base_url); - GNUNET_free (ofh); -} - - -/* end of merchant_api_patch-private-orders-ORDER_ID-forget-new.c */ diff --git a/src/lib/merchant_api_patch-private-orders-ORDER_ID-forget.c b/src/lib/merchant_api_patch-private-orders-ORDER_ID-forget.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020, 2021, 2023 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-orders-ORDER_ID-forget.c - * @brief Implementation of the PATCH /orders/$ID/forget request - * of the merchant's HTTP API + * @file merchant_api_patch-private-orders-ORDER_ID-forget-new.c + * @brief Implementation of the PATCH /private/orders/$ORDER_ID/forget request * @author Jonathan Buchanan */ #include "taler/platform.h" @@ -27,21 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a PATCH /orders/$ORDER_ID/forget operation. + * Handle for a PATCH /private/orders/$ORDER_ID/forget operation. */ -struct TALER_MERCHANT_OrderForgetHandle +struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_OrderForgetHandle /** * Function to call with the result. */ - TALER_MERCHANT_ForgetCallback cb; + TALER_MERCHANT_PatchPrivateOrdersForgetCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,37 +74,51 @@ struct TALER_MERCHANT_OrderForgetHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Order identifier. + */ + char *order_id; + + /** + * Array of JSON pointer paths to redact. + */ + char **fields; + + /** + * Number of entries in @e fields. + */ + unsigned int fields_length; }; /** * Function called when we're done processing the - * HTTP PATCH /orders/$ORDER_ID/forget request. + * HTTP PATCH /private/orders/$ORDER_ID/forget request. * - * @param cls the `struct TALER_MERCHANT_OrderForgetHandle` + * @param cls the `struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_forget_finished (void *cls, - long response_code, - const void *response) +handle_patch_orders_forget_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_OrderForgetHandle *ofh = cls; + struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateOrdersForgetResponse por = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; ofh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /orders/$ORDER_ID/forget completed with response code %u\n", + "PATCH /private/orders/$ORDER_ID/forget completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + por.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: /* fields were NOW forgotten */ @@ -109,82 +127,75 @@ handle_forget_finished (void *cls, /* fields were already forgotten before */ break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &por.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) por.hr.ec); GNUNET_break_op (0); break; } ofh->cb (ofh->cb_cls, - &hr); - TALER_MERCHANT_order_forget_cancel (ofh); + &por); + TALER_MERCHANT_patch_private_orders_forget_cancel (ofh); } -struct TALER_MERCHANT_OrderForgetHandle * -TALER_MERCHANT_order_forget ( +struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle * +TALER_MERCHANT_patch_private_orders_forget_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, + const char *url, const char *order_id, unsigned int fields_length, - const char *fields[static fields_length], - TALER_MERCHANT_ForgetCallback cb, - void *cb_cls) + const char *fields[static fields_length]) +{ + struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh; + + ofh = GNUNET_new (struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle); + ofh->ctx = ctx; + ofh->base_url = GNUNET_strdup (url); + ofh->order_id = GNUNET_strdup (order_id); + ofh->fields_length = fields_length; + ofh->fields = GNUNET_new_array (fields_length, + char *); + for (unsigned int i = 0; i < fields_length; i++) + ofh->fields[i] = GNUNET_strdup (fields[i]); + return ofh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_orders_forget_start ( + struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh, + TALER_MERCHANT_PatchPrivateOrdersForgetCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_ORDERS_FORGET_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderForgetHandle *ofh; json_t *req_fields; json_t *req_obj; + CURL *eh; - req_fields = json_array (); - if (NULL == req_fields) - { - GNUNET_break (0); - return NULL; - } - for (unsigned int i = 0; i<fields_length; i++) - { - if (0 != - json_array_append_new (req_fields, - json_string (fields[i]))) - { - GNUNET_break (0); - json_decref (req_fields); - return NULL; - } - } - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("fields", - req_fields)); - ofh = GNUNET_new (struct TALER_MERCHANT_OrderForgetHandle); - ofh->ctx = ctx; ofh->cb = cb; ofh->cb_cls = cb_cls; { @@ -192,53 +203,62 @@ TALER_MERCHANT_order_forget ( GNUNET_asprintf (&path, "private/orders/%s/forget", - order_id); - ofh->url = TALER_url_join (merchant_url, + ofh->order_id); + ofh->url = TALER_url_join (ofh->base_url, path, NULL); GNUNET_free (path); } if (NULL == ofh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_fields = json_array (); + if (NULL == req_fields) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + for (unsigned int i = 0; i < ofh->fields_length; i++) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (ofh); - return NULL; + if (0 != + json_array_append_new (req_fields, + json_string (ofh->fields[i]))) + { + json_decref (req_fields); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (ofh->url); - if (GNUNET_OK != + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("fields", + req_fields)); + eh = TALER_MERCHANT_curl_easy_get_ (ofh->url); + if ( (NULL == eh) || + (GNUNET_OK != TALER_curl_easy_post (&ofh->post_ctx, eh, - req_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (ofh); - return NULL; - } + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - ofh->job = GNUNET_CURL_job_add2 (ctx, - eh, - ofh->post_ctx.headers, - &handle_forget_finished, - ofh); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return ofh; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + ofh->job = GNUNET_CURL_job_add2 (ofh->ctx, + eh, + ofh->post_ctx.headers, + &handle_patch_orders_forget_finished, + ofh); + if (NULL == ofh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_order_forget_cancel ( - struct TALER_MERCHANT_OrderForgetHandle *ofh) +TALER_MERCHANT_patch_private_orders_forget_cancel ( + struct TALER_MERCHANT_PatchPrivateOrdersForgetHandle *ofh) { if (NULL != ofh->job) { @@ -246,9 +266,14 @@ TALER_MERCHANT_order_forget_cancel ( ofh->job = NULL; } TALER_curl_easy_post_finished (&ofh->post_ctx); + for (unsigned int i = 0; i < ofh->fields_length; i++) + GNUNET_free (ofh->fields[i]); + GNUNET_free (ofh->fields); + GNUNET_free (ofh->order_id); GNUNET_free (ofh->url); + GNUNET_free (ofh->base_url); GNUNET_free (ofh); } -/* end of merchant_api_patch_order_forget.c */ +/* end of merchant_api_patch-private-orders-ORDER_ID-forget-new.c */ diff --git a/src/lib/merchant_api_patch-private-otp-devices-DEVICE_ID-new.c b/src/lib/merchant_api_patch-private-otp-devices-DEVICE_ID-new.c @@ -1,284 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-otp-devices-DEVICE_ID-new.c - * @brief Implementation of the PATCH /private/otp-devices/$DEVICE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/otp-devices/$DEVICE_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateOtpDeviceCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * OTP device identifier. - */ - char *otp_device_id; - - /** - * Human-readable description. - */ - char *otp_device_description; - - /** - * Base32-encoded OTP secret key, or NULL to keep unchanged. - */ - char *otp_key; - - /** - * OTP algorithm. - */ - enum TALER_MerchantConfirmationAlgorithm mca; - - /** - * Counter value (for HOTP). - */ - uint64_t otp_ctr; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/otp-devices/$DEVICE_ID request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_otp_device_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateOtpDeviceResponse odr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - odh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/otp-devices/$DEVICE_ID completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - odr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_break_op (0); - break; - case MHD_HTTP_UNAUTHORIZED: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &odr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) odr.hr.ec); - GNUNET_break_op (0); - break; - } - odh->cb (odh->cb_cls, - &odr); - TALER_MERCHANT_patch_private_otp_device_cancel (odh); -} - - -struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle * -TALER_MERCHANT_patch_private_otp_device_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id, - const char *otp_device_description, - const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm mca, - uint64_t otp_ctr) -{ - struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh; - - odh = GNUNET_new (struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle); - odh->ctx = ctx; - odh->base_url = GNUNET_strdup (url); - odh->otp_device_id = GNUNET_strdup (otp_device_id); - odh->otp_device_description = GNUNET_strdup (otp_device_description); - if (NULL != otp_key) - odh->otp_key = GNUNET_strdup (otp_key); - odh->mca = mca; - odh->otp_ctr = otp_ctr; - return odh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_otp_device_start ( - struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh, - TALER_MERCHANT_PatchPrivateOtpDeviceCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - odh->cb = cb; - odh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/otp-devices/%s", - odh->otp_device_id); - odh->url = TALER_url_join (odh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == odh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("otp_device_description", - odh->otp_device_description), - GNUNET_JSON_pack_uint64 ("otp_algorithm", - (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)); - eh = TALER_MERCHANT_curl_easy_get_ (odh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&odh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - odh->job = GNUNET_CURL_job_add2 (odh->ctx, - eh, - odh->post_ctx.headers, - &handle_patch_otp_device_finished, - odh); - if (NULL == odh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_otp_device_cancel ( - struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh) -{ - if (NULL != odh->job) - { - GNUNET_CURL_job_cancel (odh->job); - odh->job = NULL; - } - TALER_curl_easy_post_finished (&odh->post_ctx); - GNUNET_free (odh->otp_device_id); - GNUNET_free (odh->otp_device_description); - GNUNET_free (odh->otp_key); - GNUNET_free (odh->url); - GNUNET_free (odh->base_url); - GNUNET_free (odh); -} - - -/* end of merchant_api_patch-private-otp-devices-DEVICE_ID-new.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 @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-otp-devices-DEVICE_ID.c - * @brief Implementation of the PATCH /otp-devices/$ID request - * of the merchant's HTTP API + * @file merchant_api_patch-private-otp-devices-DEVICE_ID-new.c + * @brief Implementation of the PATCH /private/otp-devices/$DEVICE_ID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,21 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a PATCH /otp-devices/$ID operation. + * Handle for a PATCH /private/otp-devices/$DEVICE_ID operation. */ -struct TALER_MERCHANT_OtpDevicePatchHandle +struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_OtpDevicePatchHandle /** * Function to call with the result. */ - TALER_MERCHANT_OtpDevicePatchCallback cb; + TALER_MERCHANT_PatchPrivateOtpDeviceCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,38 @@ struct TALER_MERCHANT_OtpDevicePatchHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * OTP device identifier. + */ + char *otp_device_id; + + /** + * Human-readable description. + */ + char *otp_device_description; + + /** + * Base32-encoded OTP secret key, or NULL to keep unchanged. + */ + char *otp_key; + + /** + * OTP algorithm. + */ + enum TALER_MerchantConfirmationAlgorithm mca; + + /** + * Counter value (for HOTP). + */ + uint64_t otp_ctr; }; /** * Function called when we're done processing the - * HTTP PATCH /otp-devices/$ID request. + * HTTP PATCH /private/otp-devices/$DEVICE_ID request. * - * @param cls the `struct TALER_MERCHANT_OtpDevicePatchHandle` + * @param cls the `struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,167 +114,171 @@ handle_patch_otp_device_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OtpDevicePatchHandle *tph = cls; + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateOtpDeviceResponse odr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tph->job = NULL; + odh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /otp-devices/$ID completed with response code %u\n", + "PATCH /private/otp-devices/$DEVICE_ID completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + odr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break_op (0); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &odr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) odr.hr.ec); GNUNET_break_op (0); break; } - tph->cb (tph->cb_cls, - &hr); - TALER_MERCHANT_otp_device_patch_cancel (tph); + odh->cb (odh->cb_cls, + &odr); + TALER_MERCHANT_patch_private_otp_device_cancel (odh); } -struct TALER_MERCHANT_OtpDevicePatchHandle * -TALER_MERCHANT_otp_device_patch ( +struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle * +TALER_MERCHANT_patch_private_otp_device_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *otp_device_id, const char *otp_device_description, const char *otp_key, enum TALER_MerchantConfirmationAlgorithm mca, - uint64_t otp_ctr, - TALER_MERCHANT_OtpDevicePatchCallback cb, - void *cb_cls) + uint64_t otp_ctr) +{ + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh; + + odh = GNUNET_new (struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle); + odh->ctx = ctx; + odh->base_url = GNUNET_strdup (url); + odh->otp_device_id = GNUNET_strdup (otp_device_id); + odh->otp_device_description = GNUNET_strdup (otp_device_description); + if (NULL != otp_key) + odh->otp_key = GNUNET_strdup (otp_key); + odh->mca = mca; + odh->otp_ctr = otp_ctr; + return odh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_otp_device_start ( + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh, + TALER_MERCHANT_PatchPrivateOtpDeviceCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_OTP_DEVICE_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OtpDevicePatchHandle *tph; json_t *req_obj; + CURL *eh; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("otp_device_description", - otp_device_description), - GNUNET_JSON_pack_uint64 ("otp_algorithm", - (uint32_t) mca), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("otp_key", - otp_key)), - GNUNET_JSON_pack_uint64 ("otp_ctr", - otp_ctr)); - tph = GNUNET_new (struct TALER_MERCHANT_OtpDevicePatchHandle); - tph->ctx = ctx; - tph->cb = cb; - tph->cb_cls = cb_cls; + odh->cb = cb; + odh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/otp-devices/%s", - otp_device_id); - tph->url = TALER_url_join (backend_url, + odh->otp_device_id); + odh->url = TALER_url_join (odh->base_url, path, NULL); GNUNET_free (path); } - if (NULL == tph->url) + if (NULL == odh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("otp_device_description", + odh->otp_device_description), + GNUNET_JSON_pack_uint64 ("otp_algorithm", + (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)); + eh = TALER_MERCHANT_curl_easy_get_ (odh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&odh->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&tph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - tph->job = GNUNET_CURL_job_add2 (ctx, - eh, - tph->post_ctx.headers, - &handle_patch_otp_device_finished, - tph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return tph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + odh->job = GNUNET_CURL_job_add2 (odh->ctx, + eh, + odh->post_ctx.headers, + &handle_patch_otp_device_finished, + odh); + if (NULL == odh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_otp_device_patch_cancel ( - struct TALER_MERCHANT_OtpDevicePatchHandle *tph) +TALER_MERCHANT_patch_private_otp_device_cancel ( + struct TALER_MERCHANT_PatchPrivateOtpDeviceHandle *odh) { - if (NULL != tph->job) + if (NULL != odh->job) { - GNUNET_CURL_job_cancel (tph->job); - tph->job = NULL; + GNUNET_CURL_job_cancel (odh->job); + odh->job = NULL; } - TALER_curl_easy_post_finished (&tph->post_ctx); - GNUNET_free (tph->url); - GNUNET_free (tph); + TALER_curl_easy_post_finished (&odh->post_ctx); + GNUNET_free (odh->otp_device_id); + GNUNET_free (odh->otp_device_description); + GNUNET_free (odh->otp_key); + GNUNET_free (odh->url); + GNUNET_free (odh->base_url); + GNUNET_free (odh); } -/* end of merchant_api_patch_otp_device.c */ +/* end of merchant_api_patch-private-otp-devices-DEVICE_ID-new.c */ diff --git a/src/lib/merchant_api_patch-private-products-PRODUCT_ID-new.c b/src/lib/merchant_api_patch-private-products-PRODUCT_ID-new.c @@ -1,465 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-products-PRODUCT_ID-new.c - * @brief Implementation of the PATCH /private/products/$PRODUCT_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/products/$PRODUCT_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateProductHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateProductCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Identifier of the product to update. - */ - char *product_id; - - /** - * New human-readable description. - */ - char *description; - - /** - * Internationalized descriptions (JSON). - */ - json_t *description_i18n; - - /** - * Unit of measurement. - */ - char *unit; - - /** - * New unit price. - */ - struct TALER_Amount price; - - /** - * New base64-encoded image. - */ - char *image; - - /** - * New tax information (JSON array). - */ - json_t *taxes; - - /** - * New total stock (-1 for unlimited). - */ - int64_t total_stock; - - /** - * Total units lost/expired. - */ - uint64_t total_lost; - - /** - * Storage location (JSON). - */ - json_t *address; - - /** - * Expected restock time. - */ - struct GNUNET_TIME_Timestamp next_restock; - - /** - * Optional unit prices array (for patch2 variant). - */ - const struct TALER_Amount *unit_prices; - - /** - * Number of prices in @e unit_prices. - */ - size_t unit_price_len; - - /** - * Fractional part of total stock. - */ - uint32_t total_stock_frac; - - /** - * Whether fractional quantities are allowed. - */ - bool unit_allow_fraction; - - /** - * Whether unit_allow_fraction was explicitly set. - */ - bool have_unit_allow_fraction; - - /** - * Precision level for fractions. - */ - uint32_t unit_precision_level; - - /** - * Whether unit_precision_level was explicitly set. - */ - bool have_unit_precision_level; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/products/$PRODUCT_ID request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateProductHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_product_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateProductHandle *pph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateProductResponse ppr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - pph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/products/$PRODUCT_ID completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - ppr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_break_op (0); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ - break; - case MHD_HTTP_UNAUTHORIZED: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - case MHD_HTTP_FORBIDDEN: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &ppr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ppr.hr.ec); - GNUNET_break_op (0); - break; - } - pph->cb (pph->cb_cls, - &ppr); - TALER_MERCHANT_patch_private_product_cancel (pph); -} - - -struct TALER_MERCHANT_PatchPrivateProductHandle * -TALER_MERCHANT_patch_private_product_create ( - struct GNUNET_CURL_Context *ctx, - 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) -{ - struct TALER_MERCHANT_PatchPrivateProductHandle *pph; - - pph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateProductHandle); - pph->ctx = ctx; - 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; - return pph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_patch_private_product_set_options_ ( - struct TALER_MERCHANT_PatchPrivateProductHandle *pph, - unsigned int num_options, - const struct TALER_MERCHANT_PatchPrivateProductOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - 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; - 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; - 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; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_product_start ( - struct TALER_MERCHANT_PatchPrivateProductHandle *pph, - TALER_MERCHANT_PatchPrivateProductCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - const struct TALER_Amount *prices; - size_t price_len; - char unit_total_stock_buf[64]; - - pph->cb = cb; - pph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/products/%s", - pph->product_id); - pph->url = TALER_url_join (pph->base_url, - path, - NULL); - GNUNET_free (path); - } - 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, - sizeof (unit_total_stock_buf)); - - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("product_name", - pph->description), - GNUNET_JSON_pack_string ("description", - pph->description), - GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) pph->description_i18n), - GNUNET_JSON_pack_string ("unit", - pph->unit), - TALER_JSON_pack_amount_array ("unit_price", - price_len, - prices), - GNUNET_JSON_pack_string ("image", - pph->image), - GNUNET_JSON_pack_array_incref ("taxes", - (json_t *) 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), - GNUNET_JSON_pack_timestamp ("next_restock", - pph->next_restock)); - if (pph->have_unit_allow_fraction && - pph->unit_allow_fraction) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_allow_fraction", - json_boolean ( - pph->unit_allow_fraction))); - if (pph->have_unit_precision_level) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_precision_level", - json_integer ( - pph->unit_precision_level))); - } - } - eh = TALER_MERCHANT_curl_easy_get_ (pph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pph->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - pph->job = GNUNET_CURL_job_add2 (pph->ctx, - eh, - pph->post_ctx.headers, - &handle_patch_product_finished, - pph); - if (NULL == pph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_product_cancel ( - struct TALER_MERCHANT_PatchPrivateProductHandle *pph) -{ - if (NULL != pph->job) - { - GNUNET_CURL_job_cancel (pph->job); - pph->job = NULL; - } - TALER_curl_easy_post_finished (&pph->post_ctx); - json_decref (pph->description_i18n); - json_decref (pph->taxes); - json_decref (pph->address); - 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); -} - - -/* end of merchant_api_patch-private-products-PRODUCT_ID-new.c */ diff --git a/src/lib/merchant_api_patch-private-products-PRODUCT_ID.c b/src/lib/merchant_api_patch-private-products-PRODUCT_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020, 2021 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-products-PRODUCT_ID.c - * @brief Implementation of the PATCH /products/$ID request - * of the merchant's HTTP API + * @file merchant_api_patch-private-products-PRODUCT_ID-new.c + * @brief Implementation of the PATCH /private/products/$PRODUCT_ID request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,21 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-products-PRODUCT_ID.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a PATCH /products/$ID operation. + * Handle for a PATCH /private/products/$PRODUCT_ID operation. */ -struct TALER_MERCHANT_ProductPatchHandle +struct TALER_MERCHANT_PatchPrivateProductHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_ProductPatchHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductPatchCallback cb; + TALER_MERCHANT_PatchPrivateProductCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,103 @@ struct TALER_MERCHANT_ProductPatchHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Identifier of the product to update. + */ + char *product_id; + + /** + * New human-readable description. + */ + char *description; + + /** + * Internationalized descriptions (JSON). + */ + json_t *description_i18n; + + /** + * Unit of measurement. + */ + char *unit; + + /** + * New unit price. + */ + struct TALER_Amount price; + + /** + * New base64-encoded image. + */ + char *image; + + /** + * New tax information (JSON array). + */ + json_t *taxes; + + /** + * New total stock (-1 for unlimited). + */ + int64_t total_stock; + + /** + * Total units lost/expired. + */ + uint64_t total_lost; + + /** + * Storage location (JSON). + */ + json_t *address; + + /** + * Expected restock time. + */ + struct GNUNET_TIME_Timestamp next_restock; + + /** + * Optional unit prices array (for patch2 variant). + */ + const struct TALER_Amount *unit_prices; + + /** + * Number of prices in @e unit_prices. + */ + size_t unit_price_len; + + /** + * Fractional part of total stock. + */ + uint32_t total_stock_frac; + + /** + * Whether fractional quantities are allowed. + */ + bool unit_allow_fraction; + + /** + * Whether unit_allow_fraction was explicitly set. + */ + bool have_unit_allow_fraction; + + /** + * Precision level for fractions. + */ + uint32_t unit_precision_level; + + /** + * Whether unit_precision_level was explicitly set. + */ + bool have_unit_precision_level; }; /** * Function called when we're done processing the - * HTTP PATCH /products/$ID request. + * HTTP PATCH /private/products/$PRODUCT_ID request. * - * @param cls the `struct TALER_MERCHANT_ProductPatchHandle` + * @param cls the `struct TALER_MERCHANT_PatchPrivateProductHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,157 +179,163 @@ handle_patch_product_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_ProductPatchHandle *pph = cls; + struct TALER_MERCHANT_PatchPrivateProductHandle *pph = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateProductResponse ppr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; pph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /products/$ID completed with response code %u\n", + "PATCH /private/products/$PRODUCT_ID completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ppr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break_op (0); /* This should never happen, either us * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); /* Server had an internal issue; we should retry, but this API leaves this to the application */ break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &ppr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) ppr.hr.ec); GNUNET_break_op (0); break; } pph->cb (pph->cb_cls, - &hr); - TALER_MERCHANT_product_patch_cancel (pph); + &ppr); + TALER_MERCHANT_patch_private_product_cancel (pph); } -struct TALER_MERCHANT_ProductPatchHandle * -TALER_MERCHANT_product_patch2 ( +struct TALER_MERCHANT_PatchPrivateProductHandle * +TALER_MERCHANT_patch_private_product_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *product_id, const char *description, const json_t *description_i18n, const char *unit, - const struct TALER_Amount *unit_prices, - size_t unit_price_len, + const struct TALER_Amount *price, const char *image, const json_t *taxes, int64_t total_stock, - uint32_t total_stock_frac, - bool unit_allow_fraction, - const uint32_t *unit_precision_level, uint64_t total_lost, const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - TALER_MERCHANT_ProductPatchCallback cb, - void *cb_cls) + struct GNUNET_TIME_Timestamp next_restock) { - struct TALER_MERCHANT_ProductPatchHandle *pph; - json_t *req_obj; - char unit_total_stock_buf[64]; + struct TALER_MERCHANT_PatchPrivateProductHandle *pph; - TALER_MERCHANT_format_stock_string (total_stock, - total_stock_frac, - unit_total_stock_buf, - sizeof (unit_total_stock_buf)); + pph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateProductHandle); + pph->ctx = ctx; + 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; + return pph; +} + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_product_set_options_ ( + struct TALER_MERCHANT_PatchPrivateProductHandle *pph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateProductOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) { - req_obj = GNUNET_JSON_PACK ( - /* FIXME: once we move to the new-style API, - allow applications to set the product name properly! */ - GNUNET_JSON_pack_string ("product_name", - description), - GNUNET_JSON_pack_string ("description", - description), - GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) description_i18n), - GNUNET_JSON_pack_string ("unit", - unit), - TALER_JSON_pack_amount_array ("unit_price", - unit_price_len, - unit_prices), - GNUNET_JSON_pack_string ("image", - image), - GNUNET_JSON_pack_array_incref ("taxes", - (json_t *) taxes), - GNUNET_JSON_pack_string ("unit_total_stock", - unit_total_stock_buf), - GNUNET_JSON_pack_bool ("unit_allow_fraction", - unit_allow_fraction), - GNUNET_JSON_pack_uint64 ("total_lost", - total_lost), - GNUNET_JSON_pack_object_incref ("address", - (json_t *) address), - GNUNET_JSON_pack_timestamp ("next_restock", - next_restock)); - } - if (NULL != unit_precision_level) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_precision_level", - json_integer ( - *unit_precision_level))); - } - if (! unit_allow_fraction) - { - GNUNET_assert (0 == - json_object_del (req_obj, - "unit_allow_fraction")); - if (NULL != unit_precision_level) - GNUNET_assert (0 == - json_object_del (req_obj, - "unit_precision_level")); + switch (options[i].option) + { + 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; + 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; + 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; + } } - pph = GNUNET_new (struct TALER_MERCHANT_ProductPatchHandle); - pph->ctx = ctx; + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_product_start ( + struct TALER_MERCHANT_PatchPrivateProductHandle *pph, + TALER_MERCHANT_PatchPrivateProductCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_PRODUCT_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + const struct TALER_Amount *prices; + size_t price_len; + char unit_total_stock_buf[64]; + pph->cb = cb; pph->cb_cls = cb_cls; { @@ -244,93 +343,105 @@ TALER_MERCHANT_product_patch2 ( GNUNET_asprintf (&path, "private/products/%s", - product_id); - pph->url = TALER_url_join (backend_url, + pph->product_id); + pph->url = TALER_url_join (pph->base_url, path, NULL); GNUNET_free (path); } 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) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (pph); - return NULL; + prices = pph->unit_prices; + price_len = pph->unit_price_len; } + else { - CURL *eh; + prices = &pph->price; + price_len = 1; + } - eh = TALER_MERCHANT_curl_easy_get_ (pph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&pph->post_ctx, - eh, - req_obj)) + TALER_MERCHANT_format_stock_string (pph->total_stock, + pph->total_stock_frac, + unit_total_stock_buf, + sizeof (unit_total_stock_buf)); + + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("product_name", + pph->description), + GNUNET_JSON_pack_string ("description", + pph->description), + GNUNET_JSON_pack_object_incref ("description_i18n", + (json_t *) pph->description_i18n), + GNUNET_JSON_pack_string ("unit", + pph->unit), + TALER_JSON_pack_amount_array ("unit_price", + price_len, + prices), + GNUNET_JSON_pack_string ("image", + pph->image), + GNUNET_JSON_pack_array_incref ("taxes", + (json_t *) 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), + GNUNET_JSON_pack_timestamp ("next_restock", + pph->next_restock)); + if (pph->have_unit_allow_fraction && + pph->unit_allow_fraction) + { + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_allow_fraction", + json_boolean ( + pph->unit_allow_fraction))); + if (pph->have_unit_precision_level) { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (pph); - return NULL; + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_precision_level", + json_integer ( + pph->unit_precision_level))); } + } + eh = TALER_MERCHANT_curl_easy_get_ (pph->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pph->post_ctx, + eh, + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - pph->job = GNUNET_CURL_job_add2 (ctx, - eh, - pph->post_ctx.headers, - &handle_patch_product_finished, - pph); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return pph; -} - - -struct TALER_MERCHANT_ProductPatchHandle * -TALER_MERCHANT_product_patch ( - struct GNUNET_CURL_Context *ctx, - const char *backend_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, - TALER_MERCHANT_ProductPatchCallback cb, - void *cb_cls) -{ - return TALER_MERCHANT_product_patch2 (ctx, - backend_url, - product_id, - description, - description_i18n, - unit, - price, - 1, - image, - taxes, - total_stock, - 0, - false, - NULL, - total_lost, - address, - next_restock, - cb, - cb_cls); + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + pph->job = GNUNET_CURL_job_add2 (pph->ctx, + eh, + pph->post_ctx.headers, + &handle_patch_product_finished, + pph); + if (NULL == pph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_product_patch_cancel ( - struct TALER_MERCHANT_ProductPatchHandle *pph) +TALER_MERCHANT_patch_private_product_cancel ( + struct TALER_MERCHANT_PatchPrivateProductHandle *pph) { if (NULL != pph->job) { @@ -338,9 +449,17 @@ TALER_MERCHANT_product_patch_cancel ( pph->job = NULL; } TALER_curl_easy_post_finished (&pph->post_ctx); + json_decref (pph->description_i18n); + json_decref (pph->taxes); + json_decref (pph->address); 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); } -/* end of merchant_api_patch_product.c */ +/* end of merchant_api_patch-private-products-PRODUCT_ID-new.c */ diff --git a/src/lib/merchant_api_patch-private-templates-TEMPLATE_ID-new.c b/src/lib/merchant_api_patch-private-templates-TEMPLATE_ID-new.c @@ -1,282 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-templates-TEMPLATE_ID-new.c - * @brief Implementation of the PATCH /private/templates/$TEMPLATE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/templates/$TEMPLATE_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateTemplateHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateTemplateCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Identifier of the template to update. - */ - char *template_id; - - /** - * New human-readable description. - */ - char *template_description; - - /** - * New OTP device ID, or NULL to remove association. - */ - char *otp_id; - - /** - * New template contract (JSON). - */ - json_t *template_contract; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/templates/$TEMPLATE_ID request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateTemplateHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_template_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateTemplateResponse tpr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - tph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/templates/$TEMPLATE_ID completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - tpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - tpr.hr.ec = TALER_JSON_get_error_code (json); - tpr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_break_op (0); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ - break; - case MHD_HTTP_UNAUTHORIZED: - tpr.hr.ec = TALER_JSON_get_error_code (json); - tpr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - case MHD_HTTP_FORBIDDEN: - tpr.hr.ec = TALER_JSON_get_error_code (json); - tpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - tpr.hr.ec = TALER_JSON_get_error_code (json); - tpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - tpr.hr.ec = TALER_JSON_get_error_code (json); - tpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - tpr.hr.ec = TALER_JSON_get_error_code (json); - tpr.hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &tpr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) tpr.hr.ec); - GNUNET_break_op (0); - break; - } - tph->cb (tph->cb_cls, - &tpr); - TALER_MERCHANT_patch_private_template_cancel (tph); -} - - -struct TALER_MERCHANT_PatchPrivateTemplateHandle * -TALER_MERCHANT_patch_private_template_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id, - const char *template_description, - const char *otp_id, - json_t *template_contract) -{ - struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph; - - tph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateTemplateHandle); - tph->ctx = ctx; - tph->base_url = GNUNET_strdup (url); - tph->template_id = GNUNET_strdup (template_id); - tph->template_description = GNUNET_strdup (template_description); - if (NULL != otp_id) - tph->otp_id = GNUNET_strdup (otp_id); - tph->template_contract = json_incref (template_contract); - return tph; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_template_start ( - struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph, - TALER_MERCHANT_PatchPrivateTemplateCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - tph->cb = cb; - tph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/templates/%s", - tph->template_id); - tph->url = TALER_url_join (tph->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == tph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("template_description", - tph->template_description), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("otp_id", - tph->otp_id)), - GNUNET_JSON_pack_object_incref ("template_contract", - (json_t *) tph->template_contract)); - eh = TALER_MERCHANT_curl_easy_get_ (tph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&tph->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - tph->job = GNUNET_CURL_job_add2 (tph->ctx, - eh, - tph->post_ctx.headers, - &handle_patch_template_finished, - tph); - if (NULL == tph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_template_cancel ( - struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph) -{ - if (NULL != tph->job) - { - GNUNET_CURL_job_cancel (tph->job); - tph->job = NULL; - } - TALER_curl_easy_post_finished (&tph->post_ctx); - json_decref (tph->template_contract); - GNUNET_free (tph->url); - GNUNET_free (tph->base_url); - GNUNET_free (tph->template_id); - GNUNET_free (tph->template_description); - GNUNET_free (tph->otp_id); - GNUNET_free (tph); -} - - -/* end of merchant_api_patch-private-templates-TEMPLATE_ID-new.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 @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,31 +17,35 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-templates-TEMPLATE_ID.c - * @brief Implementation of the PATCH /templates/$ID request - * of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_patch-private-templates-TEMPLATE_ID-new.c + * @brief Implementation of the PATCH /private/templates/$TEMPLATE_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a PATCH /templates/$ID operation. + * Handle for a PATCH /private/templates/$TEMPLATE_ID operation. */ -struct TALER_MERCHANT_TemplatePatchHandle +struct TALER_MERCHANT_PatchPrivateTemplateHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_TemplatePatchHandle /** * Function to call with the result. */ - TALER_MERCHANT_TemplatePatchCallback cb; + TALER_MERCHANT_PatchPrivateTemplateCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,33 @@ struct TALER_MERCHANT_TemplatePatchHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Identifier of the template to update. + */ + char *template_id; + + /** + * New human-readable description. + */ + char *template_description; + + /** + * New OTP device ID, or NULL to remove association. + */ + char *otp_id; + + /** + * New template contract (JSON). + */ + json_t *template_contract; }; /** * Function called when we're done processing the - * HTTP PATCH /templates/$ID request. + * HTTP PATCH /private/templates/$TEMPLATE_ID request. * - * @param cls the `struct TALER_MERCHANT_TemplatePatchHandle` + * @param cls the `struct TALER_MERCHANT_PatchPrivateTemplateHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,100 +109,104 @@ handle_patch_template_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TemplatePatchHandle *tph = cls; + struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateTemplateResponse tpr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; tph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /templates/$ID completed with response code %u\n", + "PATCH /private/templates/$TEMPLATE_ID completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + tpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break_op (0); /* This should never happen, either us * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tpr.hr.ec = TALER_JSON_get_error_code (json); + tpr.hr.hint = TALER_JSON_get_error_hint (json); /* Server had an internal issue; we should retry, but this API leaves this to the application */ break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &tpr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) tpr.hr.ec); GNUNET_break_op (0); break; } tph->cb (tph->cb_cls, - &hr); - TALER_MERCHANT_template_patch_cancel (tph); + &tpr); + TALER_MERCHANT_patch_private_template_cancel (tph); } -struct TALER_MERCHANT_TemplatePatchHandle * -TALER_MERCHANT_template_patch ( +struct TALER_MERCHANT_PatchPrivateTemplateHandle * +TALER_MERCHANT_patch_private_template_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *template_id, const char *template_description, const char *otp_id, - json_t *template_contract, - TALER_MERCHANT_TemplatePatchCallback cb, - void *cb_cls) + json_t *template_contract) { - struct TALER_MERCHANT_TemplatePatchHandle *tph; - json_t *req_obj; + struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("template_description", - template_description), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("otp_id", - otp_id)), - GNUNET_JSON_pack_object_incref ("template_contract", - (json_t *) template_contract)); - tph = GNUNET_new (struct TALER_MERCHANT_TemplatePatchHandle); + tph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateTemplateHandle); tph->ctx = ctx; + tph->base_url = GNUNET_strdup (url); + tph->template_id = GNUNET_strdup (template_id); + tph->template_description = GNUNET_strdup (template_description); + if (NULL != otp_id) + tph->otp_id = GNUNET_strdup (otp_id); + tph->template_contract = json_incref (template_contract); + return tph; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_template_start ( + struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph, + TALER_MERCHANT_PatchPrivateTemplateCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_TEMPLATE_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + tph->cb = cb; tph->cb_cls = cb_cls; { @@ -187,53 +214,54 @@ TALER_MERCHANT_template_patch ( GNUNET_asprintf (&path, "private/templates/%s", - template_id); - tph->url = TALER_url_join (backend_url, + tph->template_id); + tph->url = TALER_url_join (tph->base_url, path, NULL); GNUNET_free (path); } if (NULL == tph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tph->url); - if (GNUNET_OK != + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("template_description", + tph->template_description), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("otp_id", + tph->otp_id)), + GNUNET_JSON_pack_object_incref ("template_contract", + (json_t *) tph->template_contract)); + eh = TALER_MERCHANT_curl_easy_get_ (tph->url); + if ( (NULL == eh) || + (GNUNET_OK != TALER_curl_easy_post (&tph->post_ctx, eh, - req_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - tph->job = GNUNET_CURL_job_add2 (ctx, - eh, - tph->post_ctx.headers, - &handle_patch_template_finished, - tph); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return tph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + tph->job = GNUNET_CURL_job_add2 (tph->ctx, + eh, + tph->post_ctx.headers, + &handle_patch_template_finished, + tph); + if (NULL == tph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_template_patch_cancel ( - struct TALER_MERCHANT_TemplatePatchHandle *tph) +TALER_MERCHANT_patch_private_template_cancel ( + struct TALER_MERCHANT_PatchPrivateTemplateHandle *tph) { if (NULL != tph->job) { @@ -241,9 +269,14 @@ TALER_MERCHANT_template_patch_cancel ( tph->job = NULL; } TALER_curl_easy_post_finished (&tph->post_ctx); + json_decref (tph->template_contract); GNUNET_free (tph->url); + GNUNET_free (tph->base_url); + GNUNET_free (tph->template_id); + GNUNET_free (tph->template_description); + GNUNET_free (tph->otp_id); GNUNET_free (tph); } -/* end of merchant_api_patch_template.c */ +/* end of merchant_api_patch-private-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_patch-private-units-UNIT-new.c b/src/lib/merchant_api_patch-private-units-UNIT-new.c @@ -1,378 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free - Software Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-units-UNIT-new.c - * @brief Implementation of the PATCH /private/units/$UNIT request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-units-UNIT-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/units/$UNIT operation. - */ -struct TALER_MERCHANT_PatchPrivateUnitHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateUnitCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Identifier of the unit to update. - */ - char *unit_id; - - /** - * Long name of the unit (optional). - */ - const char *unit_name_long; - - /** - * Short name (symbol) of the unit (optional). - */ - const char *unit_name_short; - - /** - * Internationalized long names (JSON, optional). - */ - const json_t *unit_name_long_i18n; - - /** - * Internationalized short names (JSON, optional). - */ - const json_t *unit_name_short_i18n; - - /** - * Whether fractional quantities are allowed. - */ - bool unit_allow_fraction; - - /** - * Whether unit_allow_fraction was explicitly set. - */ - bool have_unit_allow_fraction; - - /** - * Precision level for fractions. - */ - uint32_t unit_precision_level; - - /** - * Whether unit_precision_level was explicitly set. - */ - bool have_unit_precision_level; - - /** - * Active status of the unit. - */ - bool unit_active; - - /** - * Whether unit_active was explicitly set. - */ - bool have_unit_active; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/units/$UNIT request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateUnitHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_unit_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateUnitResponse upr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - uph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/units/$UNIT completed with status %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - case MHD_HTTP_UNAUTHORIZED: - case MHD_HTTP_FORBIDDEN: - case MHD_HTTP_NOT_FOUND: - case MHD_HTTP_CONFLICT: - case MHD_HTTP_INTERNAL_SERVER_ERROR: - upr.hr.ec = TALER_JSON_get_error_code (json); - upr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case 0: - upr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &upr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response %u/%d for PATCH /private/units\n", - (unsigned int) response_code, - (int) upr.hr.ec); - GNUNET_break_op (0); - break; - } - uph->cb (uph->cb_cls, - &upr); - TALER_MERCHANT_patch_private_unit_cancel (uph); -} - - -struct TALER_MERCHANT_PatchPrivateUnitHandle * -TALER_MERCHANT_patch_private_unit_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *unit_id) -{ - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph; - - uph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateUnitHandle); - uph->ctx = ctx; - uph->base_url = GNUNET_strdup (url); - uph->unit_id = GNUNET_strdup (unit_id); - return uph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_patch_private_unit_set_options_ ( - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, - unsigned int num_options, - const struct TALER_MERCHANT_PatchPrivateUnitOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG: - uph->unit_name_long = options[i].details.unit_name_long; - break; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT: - uph->unit_name_short = options[i].details.unit_name_short; - break; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N: - uph->unit_name_long_i18n = options[i].details.unit_name_long_i18n; - break; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N: - uph->unit_name_short_i18n = options[i].details.unit_name_short_i18n; - break; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION: - uph->unit_allow_fraction = options[i].details.unit_allow_fraction; - uph->have_unit_allow_fraction = true; - break; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL: - uph->unit_precision_level = options[i].details.unit_precision_level; - uph->have_unit_precision_level = true; - break; - case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE: - uph->unit_active = options[i].details.unit_active; - uph->have_unit_active = true; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_patch_private_unit_start ( - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, - TALER_MERCHANT_PatchPrivateUnitCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - uph->cb = cb; - uph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/units/%s", - uph->unit_id); - uph->url = TALER_url_join (uph->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == uph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - - /* Build JSON request body from options that were set */ - req_obj = json_object (); - if (NULL == req_obj) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - if (NULL != uph->unit_name_long) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_name_long", - json_string (uph->unit_name_long))); - } - if (NULL != uph->unit_name_short) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_name_short", - json_string (uph->unit_name_short))); - } - if (NULL != uph->unit_name_long_i18n) - { - GNUNET_assert (0 == - json_object_set_new ( - req_obj, - "unit_name_long_i18n", - json_incref ((json_t *) uph->unit_name_long_i18n))); - } - if (NULL != uph->unit_name_short_i18n) - { - GNUNET_assert (0 == - json_object_set_new ( - req_obj, - "unit_name_short_i18n", - json_incref ((json_t *) uph->unit_name_short_i18n))); - } - if (uph->have_unit_allow_fraction) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_allow_fraction", - json_boolean ( - uph->unit_allow_fraction))); - } - if (uph->have_unit_precision_level) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_precision_level", - json_integer ( - (json_int_t) - uph->unit_precision_level))); - } - if (uph->have_unit_active) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_active", - json_boolean (uph->unit_active))); - } - eh = TALER_MERCHANT_curl_easy_get_ (uph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&uph->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - uph->job = GNUNET_CURL_job_add2 (uph->ctx, - eh, - uph->post_ctx.headers, - &handle_patch_unit_finished, - uph); - if (NULL == uph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_unit_cancel ( - struct TALER_MERCHANT_PatchPrivateUnitHandle *uph) -{ - if (NULL != uph->job) - { - GNUNET_CURL_job_cancel (uph->job); - uph->job = NULL; - } - TALER_curl_easy_post_finished (&uph->post_ctx); - GNUNET_free (uph->url); - GNUNET_free (uph->base_url); - GNUNET_free (uph->unit_id); - GNUNET_free (uph); -} - - -/* end of merchant_api_patch-private-units-UNIT-new.c */ diff --git a/src/lib/merchant_api_patch-private-units-UNIT.c b/src/lib/merchant_api_patch-private-units-UNIT.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free @@ -14,16 +14,17 @@ TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-units-UNIT.c - * @brief Implementation of PATCH /private/units/$ID - * @author Bohdan Potuzhnyi + * @file merchant_api_patch-private-units-UNIT-new.c + * @brief Implementation of the PATCH /private/units/$UNIT request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-units-UNIT.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -31,64 +32,125 @@ /** - * Handle for a PATCH /private/units/$ID operation. + * Handle for a PATCH /private/units/$UNIT operation. */ -struct TALER_MERCHANT_UnitPatchHandle +struct TALER_MERCHANT_PatchPrivateUnitHandle { /** - * Fully qualified request URL. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * In-flight CURL job. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** - * Completion callback. + * Function to call with the result. */ - TALER_MERCHANT_UnitPatchCallback cb; + TALER_MERCHANT_PatchPrivateUnitCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls; /** - * Execution context. + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; /** - * Keeps POST body and headers alive. + * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Identifier of the unit to update. + */ + char *unit_id; + + /** + * Long name of the unit (optional). + */ + const char *unit_name_long; + + /** + * Short name (symbol) of the unit (optional). + */ + const char *unit_name_short; + + /** + * Internationalized long names (JSON, optional). + */ + const json_t *unit_name_long_i18n; + + /** + * Internationalized short names (JSON, optional). + */ + const json_t *unit_name_short_i18n; + + /** + * Whether fractional quantities are allowed. + */ + bool unit_allow_fraction; + + /** + * Whether unit_allow_fraction was explicitly set. + */ + bool have_unit_allow_fraction; + + /** + * Precision level for fractions. + */ + uint32_t unit_precision_level; + + /** + * Whether unit_precision_level was explicitly set. + */ + bool have_unit_precision_level; + + /** + * Active status of the unit. + */ + bool unit_active; + + /** + * Whether unit_active was explicitly set. + */ + bool have_unit_active; }; /** - * Called when the HTTP transfer finishes. + * Function called when we're done processing the + * HTTP PATCH /private/units/$UNIT request. * - * @param cls operation handle - * @param response_code HTTP status (0 on failure) - * @param response parsed JSON reply (NULL if unavailable) + * @param cls the `struct TALER_MERCHANT_PatchPrivateUnitHandle` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON */ static void handle_patch_unit_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_UnitPatchHandle *uph = cls; + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateUnitResponse upr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; uph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/units completed with status %u\n", + "PATCH /private/units/$UNIT completed with status %u\n", (unsigned int) response_code); switch (response_code) { @@ -100,182 +162,205 @@ handle_patch_unit_finished (void *cls, case MHD_HTTP_NOT_FOUND: case MHD_HTTP_CONFLICT: case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + upr.hr.ec = TALER_JSON_get_error_code (json); + upr.hr.hint = TALER_JSON_get_error_hint (json); break; case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + upr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); + &upr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response %u/%d for PATCH /private/units\n", (unsigned int) response_code, - (int) hr.ec); + (int) upr.hr.ec); GNUNET_break_op (0); break; } uph->cb (uph->cb_cls, - &hr); - TALER_MERCHANT_unit_patch_cancel (uph); + &upr); + TALER_MERCHANT_patch_private_unit_cancel (uph); } -struct TALER_MERCHANT_UnitPatchHandle * -TALER_MERCHANT_unit_patch (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *unit_id, - const char *unit_name_long, - const char *unit_name_short, - const json_t *unit_name_long_i18n, - const json_t *unit_name_short_i18n, - const bool *unit_allow_fraction, - const uint32_t *unit_precision_level, - const bool *unit_active, - TALER_MERCHANT_UnitPatchCallback cb, - void *cb_cls) +struct TALER_MERCHANT_PatchPrivateUnitHandle * +TALER_MERCHANT_patch_private_unit_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *unit_id) { - struct TALER_MERCHANT_UnitPatchHandle *uph; - json_t *req_obj; - char *path; + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph; - req_obj = json_object (); - if (NULL == req_obj) - return NULL; - if (NULL != unit_name_long) + uph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateUnitHandle); + uph->ctx = ctx; + uph->base_url = GNUNET_strdup (url); + uph->unit_id = GNUNET_strdup (unit_id); + return uph; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_patch_private_unit_set_options_ ( + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, + unsigned int num_options, + const struct TALER_MERCHANT_PatchPrivateUnitOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) { - if (0 != json_object_set_new (req_obj, - "unit_name_long", - json_string (unit_name_long))) + switch (options[i].option) { - json_decref (req_obj); - return NULL; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG: + uph->unit_name_long = options[i].details.unit_name_long; + break; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT: + uph->unit_name_short = options[i].details.unit_name_short; + break; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_LONG_I18N: + uph->unit_name_long_i18n = options[i].details.unit_name_long_i18n; + break; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_NAME_SHORT_I18N: + uph->unit_name_short_i18n = options[i].details.unit_name_short_i18n; + break; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ALLOW_FRACTION: + uph->unit_allow_fraction = options[i].details.unit_allow_fraction; + uph->have_unit_allow_fraction = true; + break; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_PRECISION_LEVEL: + uph->unit_precision_level = options[i].details.unit_precision_level; + uph->have_unit_precision_level = true; + break; + case TALER_MERCHANT_PATCH_PRIVATE_UNIT_OPTION_UNIT_ACTIVE: + uph->unit_active = options[i].details.unit_active; + uph->have_unit_active = true; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; } } - if (NULL != unit_name_short) + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_patch_private_unit_start ( + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph, + TALER_MERCHANT_PatchPrivateUnitCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_UNIT_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + + uph->cb = cb; + uph->cb_cls = cb_cls; { - if (0 != json_object_set_new (req_obj, - "unit_name_short", - json_string (unit_name_short))) - { - json_decref (req_obj); - return NULL; - } + char *path; + + GNUNET_asprintf (&path, + "private/units/%s", + uph->unit_id); + uph->url = TALER_url_join (uph->base_url, + path, + NULL); + GNUNET_free (path); } - if (NULL != unit_name_long_i18n) + if (NULL == uph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + + /* Build JSON request body from options that were set */ + req_obj = json_object (); + if (NULL == req_obj) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + if (NULL != uph->unit_name_long) { - if (0 != json_object_set_new (req_obj, - "unit_name_long_i18n", - json_incref ((json_t *) unit_name_long_i18n))) - { - json_decref (req_obj); - return NULL; - } + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_name_long", + json_string (uph->unit_name_long))); } - if (NULL != unit_name_short_i18n) + if (NULL != uph->unit_name_short) { - if (0 != json_object_set_new (req_obj, - "unit_name_short_i18n", - json_incref ( - (json_t *) unit_name_short_i18n))) - { - json_decref (req_obj); - return NULL; - } + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_name_short", + json_string (uph->unit_name_short))); } - if (NULL != unit_allow_fraction) + if (NULL != uph->unit_name_long_i18n) { - if (0 != json_object_set_new (req_obj, - "unit_allow_fraction", - json_boolean (*unit_allow_fraction))) - { - json_decref (req_obj); - return NULL; - } + GNUNET_assert (0 == + json_object_set_new ( + req_obj, + "unit_name_long_i18n", + json_incref ((json_t *) uph->unit_name_long_i18n))); } - if (NULL != unit_precision_level) + if (NULL != uph->unit_name_short_i18n) { - if (0 != json_object_set_new (req_obj, - "unit_precision_level", - json_integer ( - (json_int_t) *unit_precision_level))) - { - json_decref (req_obj); - return NULL; - } + GNUNET_assert (0 == + json_object_set_new ( + req_obj, + "unit_name_short_i18n", + json_incref ((json_t *) uph->unit_name_short_i18n))); } - if (NULL != unit_active) + if (uph->have_unit_allow_fraction) { - if (0 != json_object_set_new (req_obj, - "unit_active", - json_boolean (*unit_active))) - { - json_decref (req_obj); - return NULL; - } + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_allow_fraction", + json_boolean ( + uph->unit_allow_fraction))); } - if (0 == json_object_size (req_obj)) + if (uph->have_unit_precision_level) { - json_decref (req_obj); - GNUNET_break (0); - return NULL; + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_precision_level", + json_integer ( + (json_int_t) + uph->unit_precision_level))); } - - GNUNET_asprintf (&path, - "private/units/%s", - unit_id); - uph = GNUNET_new (struct TALER_MERCHANT_UnitPatchHandle); - uph->ctx = ctx; - uph->cb = cb; - uph->cb_cls = cb_cls; - uph->url = TALER_url_join (backend_url, - path, - NULL); - GNUNET_free (path); - if (NULL == uph->url) + if (uph->have_unit_active) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to build /private/units/%s URL\n", - unit_id); - json_decref (req_obj); - GNUNET_free (uph); - return NULL; + GNUNET_assert (0 == + json_object_set_new (req_obj, + "unit_active", + json_boolean (uph->unit_active))); } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (uph->url); - if (GNUNET_OK != + eh = TALER_MERCHANT_curl_easy_get_ (uph->url); + if ( (NULL == eh) || + (GNUNET_OK != TALER_curl_easy_post (&uph->post_ctx, eh, - req_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (uph->url); - GNUNET_free (uph); - return NULL; - } + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - uph->job = GNUNET_CURL_job_add2 (ctx, - eh, - uph->post_ctx.headers, - &handle_patch_unit_finished, - uph); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return uph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + uph->job = GNUNET_CURL_job_add2 (uph->ctx, + eh, + uph->post_ctx.headers, + &handle_patch_unit_finished, + uph); + if (NULL == uph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_unit_patch_cancel (struct TALER_MERCHANT_UnitPatchHandle *uph) +TALER_MERCHANT_patch_private_unit_cancel ( + struct TALER_MERCHANT_PatchPrivateUnitHandle *uph) { if (NULL != uph->job) { @@ -284,8 +369,10 @@ TALER_MERCHANT_unit_patch_cancel (struct TALER_MERCHANT_UnitPatchHandle *uph) } TALER_curl_easy_post_finished (&uph->post_ctx); GNUNET_free (uph->url); + GNUNET_free (uph->base_url); + GNUNET_free (uph->unit_id); GNUNET_free (uph); } -/* end of merchant_api_patch_unit.c */ +/* end of merchant_api_patch-private-units-UNIT-new.c */ diff --git a/src/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c b/src/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c @@ -1,300 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c - * @brief Implementation of the PATCH /private/webhooks/$WEBHOOK_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a PATCH /private/webhooks/$WEBHOOK_ID operation. - */ -struct TALER_MERCHANT_PatchPrivateWebhookHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PatchPrivateWebhookCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Identifier of the webhook to update. - */ - char *webhook_id; - - /** - * New event type. - */ - char *event_type; - - /** - * New notification URL template. - */ - char *url_template; - - /** - * New HTTP method. - */ - char *http_method; - - /** - * New header template. - */ - char *header_template; - - /** - * New body template. - */ - char *body_template; -}; - - -/** - * Function called when we're done processing the - * HTTP PATCH /private/webhooks/$WEBHOOK_ID request. - * - * @param cls the `struct TALER_MERCHANT_PatchPrivateWebhookHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_patch_webhook_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PatchPrivateWebhookResponse wpr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - wph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /private/webhooks/$WEBHOOK_ID completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - wpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_break_op (0); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ - break; - case MHD_HTTP_UNAUTHORIZED: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ - break; - case MHD_HTTP_FORBIDDEN: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &wpr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) wpr.hr.ec); - GNUNET_break_op (0); - break; - } - wph->cb (wph->cb_cls, - &wpr); - TALER_MERCHANT_patch_private_webhook_cancel (wph); -} - - -struct TALER_MERCHANT_PatchPrivateWebhookHandle * -TALER_MERCHANT_patch_private_webhook_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id, - const char *event_type, - const char *url_template, - const char *http_method, - const char *header_template, - const char *body_template) -{ - struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph; - - wph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateWebhookHandle); - wph->ctx = ctx; - wph->base_url = GNUNET_strdup (url); - wph->webhook_id = GNUNET_strdup (webhook_id); - 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 TALER_ErrorCode -TALER_MERCHANT_patch_private_webhook_start ( - struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph, - TALER_MERCHANT_PatchPrivateWebhookCallback cb, - TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - wph->cb = cb; - wph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/webhooks/%s", - wph->webhook_id); - wph->url = TALER_url_join (wph->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == wph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("event_type", - wph->event_type), - GNUNET_JSON_pack_string ("url", - 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)); - eh = TALER_MERCHANT_curl_easy_get_ (wph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&wph->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - wph->job = GNUNET_CURL_job_add2 (wph->ctx, - eh, - wph->post_ctx.headers, - &handle_patch_webhook_finished, - wph); - if (NULL == wph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_patch_private_webhook_cancel ( - struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph) -{ - if (NULL != wph->job) - { - GNUNET_CURL_job_cancel (wph->job); - wph->job = NULL; - } - TALER_curl_easy_post_finished (&wph->post_ctx); - GNUNET_free (wph->url); - 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 */ diff --git a/src/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID.c b/src/lib/merchant_api_patch-private-webhooks-WEBHOOK_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,17 +17,17 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_patch-private-webhooks-WEBHOOK_ID.c - * @brief Implementation of the PATCH /webhooks/$ID request - * of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c + * @brief Implementation of the PATCH /private/webhooks/$WEBHOOK_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -35,13 +35,17 @@ /** - * Handle for a PATCH /webhooks/$ID operation. + * Handle for a PATCH /private/webhooks/$WEBHOOK_ID operation. */ -struct TALER_MERCHANT_WebhookPatchHandle +struct TALER_MERCHANT_PatchPrivateWebhookHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_WebhookPatchHandle /** * Function to call with the result. */ - TALER_MERCHANT_WebhookPatchCallback cb; + TALER_MERCHANT_PatchPrivateWebhookCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,43 @@ struct TALER_MERCHANT_WebhookPatchHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Identifier of the webhook to update. + */ + char *webhook_id; + + /** + * New event type. + */ + char *event_type; + + /** + * New notification URL template. + */ + char *url_template; + + /** + * New HTTP method. + */ + char *http_method; + + /** + * New header template. + */ + char *header_template; + + /** + * New body template. + */ + char *body_template; }; /** * Function called when we're done processing the - * HTTP PATCH /webhooks/$ID request. + * HTTP PATCH /private/webhooks/$WEBHOOK_ID request. * - * @param cls the `struct TALER_MERCHANT_WebhookPatchHandle` + * @param cls the `struct TALER_MERCHANT_PatchPrivateWebhookHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,105 +119,107 @@ handle_patch_webhook_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WebhookPatchHandle *wph = cls; + struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PatchPrivateWebhookResponse wpr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; wph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "PATCH /webhooks/$ID completed with response code %u\n", + "PATCH /private/webhooks/$WEBHOOK_ID completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break_op (0); /* This should never happen, either us * or the merchant is buggy (or API version conflict); * just pass JSON reply to the application */ break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); /* Server had an internal issue; we should retry, but this API leaves this to the application */ break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &wpr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) wpr.hr.ec); GNUNET_break_op (0); break; } wph->cb (wph->cb_cls, - &hr); - TALER_MERCHANT_webhook_patch_cancel (wph); + &wpr); + TALER_MERCHANT_patch_private_webhook_cancel (wph); } -struct TALER_MERCHANT_WebhookPatchHandle * -TALER_MERCHANT_webhook_patch ( +struct TALER_MERCHANT_PatchPrivateWebhookHandle * +TALER_MERCHANT_patch_private_webhook_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *webhook_id, const char *event_type, - const char *url, + const char *url_template, const char *http_method, const char *header_template, - const char *body_template, - TALER_MERCHANT_WebhookPatchCallback cb, - void *cb_cls) + const char *body_template) { - struct TALER_MERCHANT_WebhookPatchHandle *wph; - json_t *req_obj; + struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("event_type", - event_type), - GNUNET_JSON_pack_string ("url", - url), - GNUNET_JSON_pack_string ("http_method", - http_method), - GNUNET_JSON_pack_string ("header_template", - header_template), - GNUNET_JSON_pack_string ("body_template", - body_template)); - wph = GNUNET_new (struct TALER_MERCHANT_WebhookPatchHandle); + wph = GNUNET_new (struct TALER_MERCHANT_PatchPrivateWebhookHandle); wph->ctx = ctx; + wph->base_url = GNUNET_strdup (url); + wph->webhook_id = GNUNET_strdup (webhook_id); + 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 TALER_ErrorCode +TALER_MERCHANT_patch_private_webhook_start ( + struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph, + TALER_MERCHANT_PatchPrivateWebhookCallback cb, + TALER_MERCHANT_PATCH_PRIVATE_WEBHOOK_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + wph->cb = cb; wph->cb_cls = cb_cls; { @@ -192,53 +227,57 @@ TALER_MERCHANT_webhook_patch ( GNUNET_asprintf (&path, "private/webhooks/%s", - webhook_id); - wph->url = TALER_url_join (backend_url, + wph->webhook_id); + wph->url = TALER_url_join (wph->base_url, path, NULL); GNUNET_free (path); } if (NULL == wph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (wph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (wph->url); - if (GNUNET_OK != + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("event_type", + wph->event_type), + GNUNET_JSON_pack_string ("url", + 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)); + eh = TALER_MERCHANT_curl_easy_get_ (wph->url); + if ( (NULL == eh) || + (GNUNET_OK != TALER_curl_easy_post (&wph->post_ctx, eh, - req_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (wph); - return NULL; - } + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_PATCH)); - wph->job = GNUNET_CURL_job_add2 (ctx, - eh, - wph->post_ctx.headers, - &handle_patch_webhook_finished, - wph); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return wph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_PATCH)); + wph->job = GNUNET_CURL_job_add2 (wph->ctx, + eh, + wph->post_ctx.headers, + &handle_patch_webhook_finished, + wph); + if (NULL == wph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_webhook_patch_cancel ( - struct TALER_MERCHANT_WebhookPatchHandle *wph) +TALER_MERCHANT_patch_private_webhook_cancel ( + struct TALER_MERCHANT_PatchPrivateWebhookHandle *wph) { if (NULL != wph->job) { @@ -247,8 +286,15 @@ TALER_MERCHANT_webhook_patch_cancel ( } TALER_curl_easy_post_finished (&wph->post_ctx); GNUNET_free (wph->url); + 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_webhook.c */ +/* end of merchant_api_patch-private-webhooks-WEBHOOK_ID-new.c */ diff --git a/src/lib/merchant_api_post-management-instances-INSTANCE-auth-new.c b/src/lib/merchant_api_post-management-instances-INSTANCE-auth-new.c @@ -1,254 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-management-instances-INSTANCE-auth-new.c - * @brief Implementation of the POST /management/instances/$INSTANCE/auth request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /management/instances/$INSTANCE/auth operation. - */ -struct TALER_MERCHANT_PostManagementInstancesAuthHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostManagementInstancesAuthCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Instance identifier. - */ - char *instance_id; - - /** - * New authentication password. - */ - char *auth_password; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /management/instances/$INSTANCE/auth request. - * - * @param cls the `struct TALER_MERCHANT_PostManagementInstancesAuthHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_management_instances_auth_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostManagementInstancesAuthResponse iar = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - piah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "POST /management/instances/$INSTANCE/auth completed with " - "response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - iar.hr.ec = TALER_JSON_get_error_code (json); - iar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - iar.hr.ec = TALER_JSON_get_error_code (json); - iar.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - iar.hr.ec = TALER_JSON_get_error_code (json); - iar.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) iar.hr.ec); - break; - } - piah->cb (piah->cb_cls, - &iar); - TALER_MERCHANT_post_management_instances_auth_cancel (piah); -} - - -struct TALER_MERCHANT_PostManagementInstancesAuthHandle * -TALER_MERCHANT_post_management_instances_auth_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - const char *auth_password) -{ - struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah; - - piah = GNUNET_new (struct TALER_MERCHANT_PostManagementInstancesAuthHandle); - piah->ctx = ctx; - piah->base_url = GNUNET_strdup (url); - if (NULL != instance_id) - piah->instance_id = GNUNET_strdup (instance_id); - if (NULL != auth_password) - piah->auth_password = GNUNET_strdup (auth_password); - return piah; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_management_instances_auth_start ( - struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah, - TALER_MERCHANT_PostManagementInstancesAuthCallback cb, - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - piah->cb = cb; - piah->cb_cls = cb_cls; - if (NULL != piah->instance_id) - { - char *path; - - GNUNET_asprintf (&path, - "management/instances/%s/auth", - piah->instance_id); - piah->url = TALER_url_join (piah->base_url, - path, - NULL); - GNUNET_free (path); - } - else - { - /* backend_url is already identifying the instance */ - piah->url = TALER_url_join (piah->base_url, - "private/auth", - NULL); - } - if (NULL == piah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - - if (NULL == piah->auth_password) - { - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("method", - "external")); - } - else - { - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("method", - "token"), - GNUNET_JSON_pack_string ("password", - piah->auth_password)); - } - eh = TALER_MERCHANT_curl_easy_get_ (piah->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&piah->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_POST)); - piah->job = GNUNET_CURL_job_add2 (piah->ctx, - eh, - piah->post_ctx.headers, - & - handle_post_management_instances_auth_finished, - piah); - if (NULL == piah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_management_instances_auth_cancel ( - struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah) -{ - if (NULL != piah->job) - { - GNUNET_CURL_job_cancel (piah->job); - piah->job = NULL; - } - TALER_curl_easy_post_finished (&piah->post_ctx); - GNUNET_free (piah->instance_id); - GNUNET_free (piah->auth_password); - GNUNET_free (piah->url); - GNUNET_free (piah->base_url); - GNUNET_free (piah); -} - - -/* end of merchant_api_post-management-instances-INSTANCE-auth-new.c */ diff --git a/src/lib/merchant_api_post-management-instances-INSTANCE-auth.c b/src/lib/merchant_api_post-management-instances-INSTANCE-auth.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,8 +15,8 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-management-instances-INSTANCE-auth.c - * @brief Implementation of the POST /instance/$ID/private/auth request + * @file merchant_api_post-management-instances-INSTANCE-auth-new.c + * @brief Implementation of the POST /management/instances/$INSTANCE/auth request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,20 +25,25 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-management-instances-INSTANCE-auth.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> /** - * Handle for a POST /instances/$ID/private/auth operation. + * Handle for a POST /management/instances/$INSTANCE/auth operation. */ -struct TALER_MERCHANT_InstanceAuthPostHandle +struct TALER_MERCHANT_PostManagementInstancesAuthHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -50,12 +55,12 @@ struct TALER_MERCHANT_InstanceAuthPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstanceAuthPostCallback cb; + TALER_MERCHANT_PostManagementInstancesAuthCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -67,88 +72,109 @@ struct TALER_MERCHANT_InstanceAuthPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Instance identifier. + */ + char *instance_id; + + /** + * New authentication password. + */ + char *auth_password; }; /** * Function called when we're done processing the - * HTTP GET /instances/$ID/private/auth request. + * HTTP POST /management/instances/$INSTANCE/auth request. * - * @param cls the `struct TALER_MERCHANT_InstanceAuthPostHandle` + * @param cls the `struct TALER_MERCHANT_PostManagementInstancesAuthHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_post_instance_auth_finished (void *cls, - long response_code, - const void *response) +handle_post_management_instances_auth_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_InstanceAuthPostHandle *iaph = cls; + struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostManagementInstancesAuthResponse iar = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - iaph->job = NULL; + piah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /instances/$ID response with status code %u\n", + "POST /management/instances/$INSTANCE/auth completed with " + "response code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - /* happens if the auth token is malformed */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + iar.hr.ec = TALER_JSON_get_error_code (json); + iar.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + iar.hr.ec = TALER_JSON_get_error_code (json); + iar.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + iar.hr.ec = TALER_JSON_get_error_code (json); + iar.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) iar.hr.ec); break; } - iaph->cb (iaph->cb_cls, - &hr); - TALER_MERCHANT_instance_auth_post_cancel (iaph); + piah->cb (piah->cb_cls, + &iar); + TALER_MERCHANT_post_management_instances_auth_cancel (piah); } -struct TALER_MERCHANT_InstanceAuthPostHandle * -TALER_MERCHANT_instance_auth_post ( +struct TALER_MERCHANT_PostManagementInstancesAuthHandle * +TALER_MERCHANT_post_management_instances_auth_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, - const char *auth_password, - TALER_MERCHANT_InstanceAuthPostCallback cb, - void *cb_cls) + const char *auth_password) { - struct TALER_MERCHANT_InstanceAuthPostHandle *iaph; - json_t *req_obj; + struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah; - iaph = GNUNET_new (struct TALER_MERCHANT_InstanceAuthPostHandle); - iaph->ctx = ctx; - iaph->cb = cb; - iaph->cb_cls = cb_cls; + piah = GNUNET_new (struct TALER_MERCHANT_PostManagementInstancesAuthHandle); + piah->ctx = ctx; + piah->base_url = GNUNET_strdup (url); if (NULL != instance_id) + piah->instance_id = GNUNET_strdup (instance_id); + if (NULL != auth_password) + piah->auth_password = GNUNET_strdup (auth_password); + return piah; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_management_instances_auth_start ( + struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah, + TALER_MERCHANT_PostManagementInstancesAuthCallback cb, + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_AUTH_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + + piah->cb = cb; + piah->cb_cls = cb_cls; + if (NULL != piah->instance_id) { char *path; GNUNET_asprintf (&path, "management/instances/%s/auth", - instance_id); - iaph->url = TALER_url_join (backend_url, + piah->instance_id); + piah->url = TALER_url_join (piah->base_url, path, NULL); GNUNET_free (path); @@ -156,18 +182,14 @@ TALER_MERCHANT_instance_auth_post ( else { /* backend_url is already identifying the instance */ - iaph->url = TALER_url_join (backend_url, + piah->url = TALER_url_join (piah->base_url, "private/auth", NULL); } - if (NULL == iaph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (iaph); - return NULL; - } - if (NULL == auth_password) + if (NULL == piah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + + if (NULL == piah->auth_password) { req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("method", @@ -179,49 +201,54 @@ TALER_MERCHANT_instance_auth_post ( GNUNET_JSON_pack_string ("method", "token"), GNUNET_JSON_pack_string ("password", - auth_password)); + piah->auth_password)); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - iaph->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (iaph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&iaph->post_ctx, + eh = TALER_MERCHANT_curl_easy_get_ (piah->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&piah->post_ctx, eh, - req_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (iaph->url); - GNUNET_free (iaph); - return NULL; - } + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_POST)); - iaph->job = GNUNET_CURL_job_add2 (ctx, - eh, - iaph->post_ctx.headers, - &handle_post_instance_auth_finished, - iaph); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return iaph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_POST)); + piah->job = GNUNET_CURL_job_add2 (piah->ctx, + eh, + piah->post_ctx.headers, + & + handle_post_management_instances_auth_finished, + piah); + if (NULL == piah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instance_auth_post_cancel ( - struct TALER_MERCHANT_InstanceAuthPostHandle *iaph) +TALER_MERCHANT_post_management_instances_auth_cancel ( + struct TALER_MERCHANT_PostManagementInstancesAuthHandle *piah) { - if (NULL != iaph->job) - GNUNET_CURL_job_cancel (iaph->job); - TALER_curl_easy_post_finished (&iaph->post_ctx); - GNUNET_free (iaph->url); - GNUNET_free (iaph); + if (NULL != piah->job) + { + GNUNET_CURL_job_cancel (piah->job); + piah->job = NULL; + } + TALER_curl_easy_post_finished (&piah->post_ctx); + GNUNET_free (piah->instance_id); + GNUNET_free (piah->auth_password); + GNUNET_free (piah->url); + GNUNET_free (piah->base_url); + GNUNET_free (piah); } + + +/* end of merchant_api_post-management-instances-INSTANCE-auth-new.c */ diff --git a/src/lib/merchant_api_post-management-instances-new.c b/src/lib/merchant_api_post-management-instances-new.c @@ -1,333 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-management-instances-new.c - * @brief Implementation of the POST /management/instances request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-management-instances-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /management/instances operation. - */ -struct TALER_MERCHANT_PostManagementInstancesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostManagementInstancesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Instance identifier. - */ - char *instance_id; - - /** - * Human-readable name. - */ - char *name; - - /** - * Address (JSON). - */ - json_t *address; - - /** - * Jurisdiction (JSON). - */ - json_t *jurisdiction; - - /** - * Whether to use the STEFAN curve. - */ - bool use_stefan; - - /** - * Default wire transfer delay. - */ - struct GNUNET_TIME_Relative default_wire_transfer_delay; - - /** - * Default payment deadline. - */ - struct GNUNET_TIME_Relative default_pay_delay; - - /** - * Default refund deadline. - */ - struct GNUNET_TIME_Relative default_refund_delay; - - /** - * Authentication password (or NULL). - */ - char *auth_password; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /management/instances request. - * - * @param cls the `struct TALER_MERCHANT_PostManagementInstancesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_management_instances_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostManagementInstancesHandle *pmih = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostManagementInstancesResponse mir = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - pmih->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /management/instances completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - mir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - mir.hr.ec = TALER_JSON_get_error_code (json); - mir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - mir.hr.ec = TALER_JSON_get_error_code (json); - mir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - mir.hr.ec = TALER_JSON_get_error_code (json); - mir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - mir.hr.ec = TALER_JSON_get_error_code (json); - mir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - mir.hr.ec = TALER_JSON_get_error_code (json); - mir.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - mir.hr.ec = TALER_JSON_get_error_code (json); - mir.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &mir.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) mir.hr.ec); - GNUNET_break_op (0); - break; - } - pmih->cb (pmih->cb_cls, - &mir); - TALER_MERCHANT_post_management_instances_cancel (pmih); -} - - -struct TALER_MERCHANT_PostManagementInstancesHandle * -TALER_MERCHANT_post_management_instances_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *instance_id, - 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) -{ - struct TALER_MERCHANT_PostManagementInstancesHandle *pmih; - - pmih = GNUNET_new (struct TALER_MERCHANT_PostManagementInstancesHandle); - pmih->ctx = ctx; - pmih->base_url = GNUNET_strdup (url); - pmih->instance_id = GNUNET_strdup (instance_id); - pmih->name = GNUNET_strdup (name); - 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 TALER_ErrorCode -TALER_MERCHANT_post_management_instances_start ( - struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, - TALER_MERCHANT_PostManagementInstancesCallback cb, - TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - json_t *auth_obj; - CURL *eh; - - pmih->cb = cb; - pmih->cb_cls = cb_cls; - pmih->url = TALER_url_join (pmih->base_url, - "management/instances", - NULL); - if (NULL == pmih->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - if (NULL != pmih->auth_password) - { - auth_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("method", - "token"), - GNUNET_JSON_pack_string ("password", - pmih->auth_password)); - } - else - { - auth_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("method", - "external")); - } - if (NULL == auth_obj) - { - GNUNET_break (0); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("id", - pmih->instance_id), - GNUNET_JSON_pack_string ("name", - pmih->name), - GNUNET_JSON_pack_object_incref ("address", - pmih->address), - GNUNET_JSON_pack_object_incref ("jurisdiction", - 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_object_steal ("auth", - auth_obj)); - eh = TALER_MERCHANT_curl_easy_get_ (pmih->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pmih->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - pmih->job = GNUNET_CURL_job_add2 (pmih->ctx, - eh, - pmih->post_ctx.headers, - &handle_post_management_instances_finished, - pmih); - if (NULL == pmih->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_management_instances_cancel ( - struct TALER_MERCHANT_PostManagementInstancesHandle *pmih) -{ - if (NULL != pmih->job) - { - GNUNET_CURL_job_cancel (pmih->job); - pmih->job = NULL; - } - TALER_curl_easy_post_finished (&pmih->post_ctx); - json_decref (pmih->address); - json_decref (pmih->jurisdiction); - GNUNET_free (pmih->instance_id); - GNUNET_free (pmih->name); - GNUNET_free (pmih->auth_password); - GNUNET_free (pmih->url); - GNUNET_free (pmih->base_url); - GNUNET_free (pmih); -} - - -/* end of merchant_api_post-management-instances-new.c */ diff --git a/src/lib/merchant_api_post-management-instances.c b/src/lib/merchant_api_post-management-instances.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2023 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-management-instances.c - * @brief Implementation of the POST /instances request - * of the merchant's HTTP API + * @file merchant_api_post-management-instances-new.c + * @brief Implementation of the POST /management/instances request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,22 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-management-instances.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> -#include <taler/taler_kyclogic_lib.h> /** - * Handle for a POST /instances/$ID operation. + * Handle for a POST /management/instances operation. */ -struct TALER_MERCHANT_InstancesPostHandle +struct TALER_MERCHANT_PostManagementInstancesHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -54,12 +57,12 @@ struct TALER_MERCHANT_InstancesPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstancesPostCallback cb; + TALER_MERCHANT_PostManagementInstancesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -71,98 +74,129 @@ struct TALER_MERCHANT_InstancesPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Instance identifier. + */ + char *instance_id; + + /** + * Human-readable name. + */ + char *name; + + /** + * Address (JSON). + */ + json_t *address; + + /** + * Jurisdiction (JSON). + */ + json_t *jurisdiction; + + /** + * Whether to use the STEFAN curve. + */ + bool use_stefan; + + /** + * Default wire transfer delay. + */ + struct GNUNET_TIME_Relative default_wire_transfer_delay; + + /** + * Default payment deadline. + */ + struct GNUNET_TIME_Relative default_pay_delay; + + /** + * Default refund deadline. + */ + struct GNUNET_TIME_Relative default_refund_delay; + + /** + * Authentication password (or NULL). + */ + char *auth_password; }; /** * Function called when we're done processing the - * HTTP POST /instances request. + * HTTP POST /management/instances request. * - * @param cls the `struct TALER_MERCHANT_InstancesPostHandle` + * @param cls the `struct TALER_MERCHANT_PostManagementInstancesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_post_instances_finished (void *cls, - long response_code, - const void *response) +handle_post_management_instances_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_InstancesPostHandle *iph = cls; + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostManagementInstancesResponse mir = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - iph->job = NULL; + pmih->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "POST /management/instances completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + mir.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + mir.hr.ec = TALER_JSON_get_error_code (json); + mir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + mir.hr.ec = TALER_JSON_get_error_code (json); + mir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + mir.hr.ec = TALER_JSON_get_error_code (json); + mir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ + mir.hr.ec = TALER_JSON_get_error_code (json); + mir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + mir.hr.ec = TALER_JSON_get_error_code (json); + mir.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + mir.hr.ec = TALER_JSON_get_error_code (json); + mir.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &mir.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) mir.hr.ec); GNUNET_break_op (0); break; } - iph->cb (iph->cb_cls, - &hr); - TALER_MERCHANT_instances_post_cancel (iph); + pmih->cb (pmih->cb_cls, + &mir); + TALER_MERCHANT_post_management_instances_cancel (pmih); } -struct TALER_MERCHANT_InstancesPostHandle * -TALER_MERCHANT_instances_post ( +struct TALER_MERCHANT_PostManagementInstancesHandle * +TALER_MERCHANT_post_management_instances_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, const char *name, const json_t *address, @@ -171,21 +205,51 @@ TALER_MERCHANT_instances_post ( 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, - TALER_MERCHANT_InstancesPostCallback cb, - void *cb_cls) + const char *auth_password) +{ + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih; + + pmih = GNUNET_new (struct TALER_MERCHANT_PostManagementInstancesHandle); + pmih->ctx = ctx; + pmih->base_url = GNUNET_strdup (url); + pmih->instance_id = GNUNET_strdup (instance_id); + pmih->name = GNUNET_strdup (name); + 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 TALER_ErrorCode +TALER_MERCHANT_post_management_instances_start ( + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih, + TALER_MERCHANT_PostManagementInstancesCallback cb, + TALER_MERCHANT_POST_MANAGEMENT_INSTANCES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_InstancesPostHandle *iph; json_t *req_obj; json_t *auth_obj; + CURL *eh; - if (NULL != auth_password) + pmih->cb = cb; + pmih->cb_cls = cb_cls; + pmih->url = TALER_url_join (pmih->base_url, + "management/instances", + NULL); + if (NULL == pmih->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + if (NULL != pmih->auth_password) { auth_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("method", "token"), GNUNET_JSON_pack_string ("password", - auth_password)); + pmih->auth_password)); } else { @@ -196,85 +260,74 @@ TALER_MERCHANT_instances_post ( if (NULL == auth_obj) { GNUNET_break (0); - return NULL; + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("id", - instance_id), + pmih->instance_id), GNUNET_JSON_pack_string ("name", - name), + pmih->name), GNUNET_JSON_pack_object_incref ("address", - (json_t *) address), + pmih->address), GNUNET_JSON_pack_object_incref ("jurisdiction", - (json_t *) jurisdiction), + pmih->jurisdiction), GNUNET_JSON_pack_bool ("use_stefan", - use_stefan), + pmih->use_stefan), GNUNET_JSON_pack_time_rel ("default_wire_transfer_delay", - default_wire_transfer_delay), + pmih->default_wire_transfer_delay), GNUNET_JSON_pack_time_rel ("default_pay_delay", - default_pay_delay), + pmih->default_pay_delay), GNUNET_JSON_pack_time_rel ("default_refund_delay", - default_refund_delay), - /* FIXME: add eventually to arguments when we transform the API... */ + pmih->default_refund_delay), GNUNET_JSON_pack_time_rounder_interval ( "default_wire_transfer_rounding_interval", GNUNET_TIME_RI_NONE), GNUNET_JSON_pack_object_steal ("auth", auth_obj)); - iph = GNUNET_new (struct TALER_MERCHANT_InstancesPostHandle); - iph->ctx = ctx; - iph->cb = cb; - iph->cb_cls = cb_cls; - iph->url = TALER_url_join (backend_url, - "management/instances", - NULL); - if (NULL == iph->url) + eh = TALER_MERCHANT_curl_easy_get_ (pmih->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pmih->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (iph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (iph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&iph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (iph); - return NULL; - } - json_decref (req_obj); - iph->job = GNUNET_CURL_job_add2 (ctx, - eh, - iph->post_ctx.headers, - &handle_post_instances_finished, - iph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return iph; + json_decref (req_obj); + pmih->job = GNUNET_CURL_job_add2 (pmih->ctx, + eh, + pmih->post_ctx.headers, + &handle_post_management_instances_finished, + pmih); + if (NULL == pmih->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instances_post_cancel ( - struct TALER_MERCHANT_InstancesPostHandle *iph) +TALER_MERCHANT_post_management_instances_cancel ( + struct TALER_MERCHANT_PostManagementInstancesHandle *pmih) { - if (NULL != iph->job) + if (NULL != pmih->job) { - GNUNET_CURL_job_cancel (iph->job); - iph->job = NULL; + GNUNET_CURL_job_cancel (pmih->job); + pmih->job = NULL; } - TALER_curl_easy_post_finished (&iph->post_ctx); - GNUNET_free (iph->url); - GNUNET_free (iph); + TALER_curl_easy_post_finished (&pmih->post_ctx); + json_decref (pmih->address); + json_decref (pmih->jurisdiction); + GNUNET_free (pmih->instance_id); + GNUNET_free (pmih->name); + GNUNET_free (pmih->auth_password); + GNUNET_free (pmih->url); + GNUNET_free (pmih->base_url); + GNUNET_free (pmih); } -/* end of merchant_api_post_instances.c */ +/* end of merchant_api_post-management-instances-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-abort-new.c b/src/lib/merchant_api_post-orders-ORDER_ID-abort-new.c @@ -1,432 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-orders-ORDER_ID-abort-new.c - * @brief Implementation of the POST /orders/$ID/abort request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-abort-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> -#include <taler/taler_signatures.h> - - -/** - * Maximum number of refunds we return. - */ -#define MAX_REFUNDS 1024 - - -/** - * Handle for a POST /orders/$ORDER_ID/abort operation. - */ -struct TALER_MERCHANT_PostOrdersAbortHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostOrdersAbortCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order identifier. - */ - char *order_id; - - /** - * Public key of the merchant. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Hash of the contract terms. - */ - struct TALER_PrivateContractHashP h_contract; - - /** - * The coins we are aborting on. - */ - struct TALER_MERCHANT_PostOrdersAbortCoin *coins; - - /** - * Number of @e coins. - */ - unsigned int num_coins; -}; - - -/** - * Check that the response for an abort is well-formed, - * and call the application callback with the result if it is - * OK. Otherwise returns #GNUNET_SYSERR. - * - * @param poah handle to operation that created the reply - * @param[in] ar abort response, partially initialized - * @param json the reply to parse - * @return #GNUNET_OK on success - */ -static enum GNUNET_GenericReturnValue -check_abort_refund (struct TALER_MERCHANT_PostOrdersAbortHandle *poah, - struct TALER_MERCHANT_PostOrdersAbortResponse *ar, - const json_t *json) -{ - const json_t *refunds; - unsigned int num_refunds; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ("refunds", - &refunds), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - num_refunds = (unsigned int) json_array_size (refunds); - if ( (json_array_size (refunds) != (size_t) num_refunds) || - (num_refunds > MAX_REFUNDS) ) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - - { - struct TALER_MERCHANT_PostOrdersAbortedCoin res[GNUNET_NZL (num_refunds)]; - - for (unsigned int i = 0; i<num_refunds; i++) - { - json_t *refund = json_array_get (refunds, i); - uint32_t exchange_status; - struct GNUNET_JSON_Specification spec_es[] = { - GNUNET_JSON_spec_uint32 ("exchange_status", - &exchange_status), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (refund, - spec_es, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (MHD_HTTP_OK == exchange_status) - { - struct GNUNET_JSON_Specification spec_detail[] = { - GNUNET_JSON_spec_fixed_auto ("exchange_sig", - &res[i].exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", - &res[i].exchange_pub), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (refund, - spec_detail, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - res[i].coin_pub = poah->coins[i].coin_pub; - - if (GNUNET_OK != - TALER_exchange_online_refund_confirmation_verify ( - &poah->h_contract, - &poah->coins[i].coin_pub, - &poah->merchant_pub, - 0, /* transaction id */ - &poah->coins[i].amount_with_fee, - &res[i].exchange_pub, - &res[i].exchange_sig)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - } - } - ar->details.ok.num_aborts = num_refunds; - ar->details.ok.aborts = res; - poah->cb (poah->cb_cls, - ar); - poah->cb = NULL; - } - return GNUNET_OK; -} - - -/** - * Function called when we're done processing the - * HTTP POST /orders/$ID/abort request. - * - * @param cls the `struct TALER_MERCHANT_PostOrdersAbortHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_abort_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostOrdersAbortHandle *poah = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostOrdersAbortResponse ar = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - poah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /orders/$ID/abort completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - ar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - if (GNUNET_OK == - check_abort_refund (poah, - &ar, - json)) - { - TALER_MERCHANT_post_orders_abort_cancel (poah); - return; - } - ar.hr.http_status = 0; - ar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_BAD_REQUEST: - ar.hr.ec = TALER_JSON_get_error_code (json); - ar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - ar.hr.ec = TALER_JSON_get_error_code (json); - ar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - ar.hr.ec = TALER_JSON_get_error_code (json); - ar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_REQUEST_TIMEOUT: - ar.hr.ec = TALER_JSON_get_error_code (json); - ar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_PRECONDITION_FAILED: - ar.hr.ec = TALER_JSON_get_error_code (json); - ar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - ar.hr.ec = TALER_JSON_get_error_code (json); - ar.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_BAD_GATEWAY: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &ar.hr); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &ar.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ar.hr.ec); - GNUNET_break_op (0); - break; - } - poah->cb (poah->cb_cls, - &ar); - TALER_MERCHANT_post_orders_abort_cancel (poah); -} - - -struct TALER_MERCHANT_PostOrdersAbortHandle * -TALER_MERCHANT_post_orders_abort_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_PrivateContractHashP *h_contract, - unsigned int num_coins, - const struct TALER_MERCHANT_PostOrdersAbortCoin coins[static num_coins]) -{ - struct TALER_MERCHANT_PostOrdersAbortHandle *poah; - - poah = GNUNET_new (struct TALER_MERCHANT_PostOrdersAbortHandle); - poah->ctx = ctx; - poah->base_url = GNUNET_strdup (url); - poah->order_id = GNUNET_strdup (order_id); - poah->merchant_pub = *merchant_pub; - poah->h_contract = *h_contract; - poah->num_coins = num_coins; - poah->coins = GNUNET_new_array (num_coins, - struct TALER_MERCHANT_PostOrdersAbortCoin); - GNUNET_memcpy (poah->coins, - coins, - num_coins * sizeof (struct TALER_MERCHANT_PostOrdersAbortCoin)) - ; - return poah; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_abort_start ( - struct TALER_MERCHANT_PostOrdersAbortHandle *poah, - TALER_MERCHANT_PostOrdersAbortCallback cb, - TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cb_cls) -{ - json_t *abort_obj; - json_t *j_coins; - CURL *eh; - - poah->cb = cb; - poah->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/abort", - poah->order_id); - poah->url = TALER_url_join (poah->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == poah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - j_coins = json_array (); - if (NULL == j_coins) - { - GNUNET_break (0); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - for (unsigned int i = 0; i<poah->num_coins; i++) - { - const struct TALER_MERCHANT_PostOrdersAbortCoin *ac = &poah->coins[i]; - json_t *j_coin; - - j_coin = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("coin_pub", - &ac->coin_pub), - TALER_JSON_pack_amount ("contribution", - &ac->amount_with_fee), - GNUNET_JSON_pack_string ("exchange_url", - ac->exchange_url)); - if (0 != - json_array_append_new (j_coins, - j_coin)) - { - GNUNET_break (0); - json_decref (j_coins); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - abort_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("coins", - j_coins), - GNUNET_JSON_pack_data_auto ("h_contract", - &poah->h_contract)); - eh = TALER_MERCHANT_curl_easy_get_ (poah->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&poah->post_ctx, - eh, - abort_obj)) ) - { - GNUNET_break (0); - json_decref (abort_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (abort_obj); - poah->job = GNUNET_CURL_job_add2 (poah->ctx, - eh, - poah->post_ctx.headers, - &handle_abort_finished, - poah); - if (NULL == poah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_orders_abort_cancel ( - struct TALER_MERCHANT_PostOrdersAbortHandle *poah) -{ - if (NULL != poah->job) - { - GNUNET_CURL_job_cancel (poah->job); - poah->job = NULL; - } - TALER_curl_easy_post_finished (&poah->post_ctx); - GNUNET_free (poah->coins); - GNUNET_free (poah->order_id); - GNUNET_free (poah->url); - GNUNET_free (poah->base_url); - GNUNET_free (poah); -} - - -/* end of merchant_api_post-orders-ORDER_ID-abort-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-abort.c b/src/lib/merchant_api_post-orders-ORDER_ID-abort.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,11 +17,9 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-orders-ORDER_ID-abort.c + * @file merchant_api_post-orders-ORDER_ID-abort-new.c * @brief Implementation of the POST /orders/$ID/abort request - * of the merchant's HTTP API * @author Christian Grothoff - * @author Marcello Stanisci */ #include "taler/platform.h" #include <curl/curl.h> @@ -29,13 +27,12 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-orders-ORDER_ID-abort.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> -#include <taler/taler_exchange_service.h> #include <taler/taler_curl_lib.h> +#include <taler/taler_signatures.h> /** @@ -45,22 +42,17 @@ /** - * @brief An abort Handle + * Handle for a POST /orders/$ORDER_ID/abort operation. */ -struct TALER_MERCHANT_OrderAbortHandle +struct TALER_MERCHANT_PostOrdersAbortHandle { /** - * Hash of the contract. + * Base URL of the merchant backend. */ - struct TALER_PrivateContractHashP h_contract_terms; - - /** - * Public key of the merchant. - */ - struct TALER_MerchantPublicKeyP merchant_pub; + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -72,12 +64,12 @@ struct TALER_MERCHANT_OrderAbortHandle /** * Function to call with the result. */ - TALER_MERCHANT_AbortCallback abort_cb; + TALER_MERCHANT_PostOrdersAbortCallback cb; /** - * Closure for @a abort_cb. + * Closure for @a cb. */ - void *abort_cb_cls; + TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -90,15 +82,29 @@ struct TALER_MERCHANT_OrderAbortHandle struct TALER_CURL_PostContext post_ctx; /** + * Order identifier. + */ + char *order_id; + + /** + * Public key of the merchant. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Hash of the contract terms. + */ + struct TALER_PrivateContractHashP h_contract; + + /** * The coins we are aborting on. */ - struct TALER_MERCHANT_AbortCoin *coins; + struct TALER_MERCHANT_PostOrdersAbortCoin *coins; /** - * Number of @e coins we are paying with. + * Number of @e coins. */ unsigned int num_coins; - }; @@ -107,14 +113,14 @@ struct TALER_MERCHANT_OrderAbortHandle * and call the application callback with the result if it is * OK. Otherwise returns #GNUNET_SYSERR. * - * @param oah handle to operation that created the reply + * @param poah handle to operation that created the reply * @param[in] ar abort response, partially initialized * @param json the reply to parse * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue -check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, - struct TALER_MERCHANT_AbortResponse *ar, +check_abort_refund (struct TALER_MERCHANT_PostOrdersAbortHandle *poah, + struct TALER_MERCHANT_PostOrdersAbortResponse *ar, const json_t *json) { const json_t *refunds; @@ -134,7 +140,7 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, return GNUNET_SYSERR; } num_refunds = (unsigned int) json_array_size (refunds); - if ( (json_array_size (refunds) != (size_t) num_refunds) || + if ( (json_array_size (refunds) != (size_t) num_refunds) || (num_refunds > MAX_REFUNDS) ) { GNUNET_break (0); @@ -142,7 +148,7 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, } { - struct TALER_MERCHANT_AbortedCoin res[GNUNET_NZL (num_refunds)]; + struct TALER_MERCHANT_PostOrdersAbortedCoin res[GNUNET_NZL (num_refunds)]; for (unsigned int i = 0; i<num_refunds; i++) { @@ -180,14 +186,15 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, GNUNET_break_op (0); return GNUNET_SYSERR; } + res[i].coin_pub = poah->coins[i].coin_pub; if (GNUNET_OK != TALER_exchange_online_refund_confirmation_verify ( - &oah->h_contract_terms, - &oah->coins[i].coin_pub, - &oah->merchant_pub, - 0, /* transaction id */ - &oah->coins[i].amount_with_fee, + &poah->h_contract, + &poah->coins[i].coin_pub, + &poah->merchant_pub, + 0, /* transaction id */ + &poah->coins[i].amount_with_fee, &res[i].exchange_pub, &res[i].exchange_sig)) { @@ -196,12 +203,11 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, } } } - ar->details.ok.merchant_pub = &oah->merchant_pub; ar->details.ok.num_aborts = num_refunds; ar->details.ok.aborts = res; - oah->abort_cb (oah->abort_cb_cls, - ar); - oah->abort_cb = NULL; + poah->cb (poah->cb_cls, + ar); + poah->cb = NULL; } return GNUNET_OK; } @@ -209,9 +215,9 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, /** * Function called when we're done processing the - * abort request. + * HTTP POST /orders/$ID/abort request. * - * @param cls the `struct TALER_MERCHANT_OrderAbortHandle` + * @param cls the `struct TALER_MERCHANT_PostOrdersAbortHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -220,16 +226,16 @@ handle_abort_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrderAbortHandle *oah = cls; + struct TALER_MERCHANT_PostOrdersAbortHandle *poah = cls; const json_t *json = response; - struct TALER_MERCHANT_AbortResponse ar = { + struct TALER_MERCHANT_PostOrdersAbortResponse ar = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - oah->job = NULL; + poah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "/pay completed with response code %u\n", + "POST /orders/$ID/abort completed with response code %u\n", (unsigned int) response_code); switch (response_code) { @@ -238,11 +244,11 @@ handle_abort_finished (void *cls, break; case MHD_HTTP_OK: if (GNUNET_OK == - check_abort_refund (oah, + check_abort_refund (poah, &ar, json)) { - TALER_MERCHANT_order_abort_cancel (oah); + TALER_MERCHANT_post_orders_abort_cancel (poah); return; } ar.hr.http_status = 0; @@ -251,9 +257,6 @@ handle_abort_finished (void *cls, case MHD_HTTP_BAD_REQUEST: ar.hr.ec = TALER_JSON_get_error_code (json); ar.hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us or the - merchant is buggy (or API version conflict); just - pass JSON reply to the application */ break; case MHD_HTTP_FORBIDDEN: ar.hr.ec = TALER_JSON_get_error_code (json); @@ -262,38 +265,25 @@ handle_abort_finished (void *cls, case MHD_HTTP_NOT_FOUND: ar.hr.ec = TALER_JSON_get_error_code (json); ar.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ break; case MHD_HTTP_REQUEST_TIMEOUT: ar.hr.ec = TALER_JSON_get_error_code (json); ar.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says one of - the signatures is invalid; as we checked them, - this should never happen, we should pass the JSON - reply to the application */ break; case MHD_HTTP_PRECONDITION_FAILED: - /* Our *payment* already succeeded fully. */ ar.hr.ec = TALER_JSON_get_error_code (json); ar.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: ar.hr.ec = TALER_JSON_get_error_code (json); ar.hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ break; case MHD_HTTP_BAD_GATEWAY: TALER_MERCHANT_parse_error_details_ (json, response_code, &ar.hr); - /* Nothing really to verify, the merchant is blaming the exchange. - We should pass the JSON reply to the application */ break; default: - /* unexpected response code */ TALER_MERCHANT_parse_error_details_ (json, response_code, &ar.hr); @@ -304,44 +294,80 @@ handle_abort_finished (void *cls, GNUNET_break_op (0); break; } - oah->abort_cb (oah->abort_cb_cls, - &ar); - TALER_MERCHANT_order_abort_cancel (oah); + poah->cb (poah->cb_cls, + &ar); + TALER_MERCHANT_post_orders_abort_cancel (poah); } -struct TALER_MERCHANT_OrderAbortHandle * -TALER_MERCHANT_order_abort ( +struct TALER_MERCHANT_PostOrdersAbortHandle * +TALER_MERCHANT_post_orders_abort_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, + const char *url, const char *order_id, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_PrivateContractHashP *h_contract, unsigned int num_coins, - const struct TALER_MERCHANT_AbortCoin coins[static num_coins], - TALER_MERCHANT_AbortCallback cb, - void *cb_cls) + const struct TALER_MERCHANT_PostOrdersAbortCoin coins[static num_coins]) +{ + struct TALER_MERCHANT_PostOrdersAbortHandle *poah; + + poah = GNUNET_new (struct TALER_MERCHANT_PostOrdersAbortHandle); + poah->ctx = ctx; + poah->base_url = GNUNET_strdup (url); + poah->order_id = GNUNET_strdup (order_id); + poah->merchant_pub = *merchant_pub; + poah->h_contract = *h_contract; + poah->num_coins = num_coins; + poah->coins = GNUNET_new_array (num_coins, + struct TALER_MERCHANT_PostOrdersAbortCoin); + GNUNET_memcpy (poah->coins, + coins, + num_coins * sizeof (struct TALER_MERCHANT_PostOrdersAbortCoin)) + ; + return poah; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_abort_start ( + struct TALER_MERCHANT_PostOrdersAbortHandle *poah, + TALER_MERCHANT_PostOrdersAbortCallback cb, + TALER_MERCHANT_POST_ORDERS_ABORT_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderAbortHandle *oah; json_t *abort_obj; json_t *j_coins; + CURL *eh; + + poah->cb = cb; + poah->cb_cls = cb_cls; + { + char *path; + GNUNET_asprintf (&path, + "orders/%s/abort", + poah->order_id); + poah->url = TALER_url_join (poah->base_url, + path, + NULL); + GNUNET_free (path); + } + if (NULL == poah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; j_coins = json_array (); if (NULL == j_coins) { GNUNET_break (0); - return NULL; + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - for (unsigned int i = 0; i<num_coins; i++) + for (unsigned int i = 0; i<poah->num_coins; i++) { - const struct TALER_MERCHANT_AbortCoin *ac = &coins[i]; + const struct TALER_MERCHANT_PostOrdersAbortCoin *ac = &poah->coins[i]; json_t *j_coin; - /* create JSON for this coin */ j_coin = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("coin_pub", &ac->coin_pub), - /* FIXME: no longer needed since **v18**, remove eventually! */ TALER_JSON_pack_amount ("contribution", &ac->amount_with_fee), GNUNET_JSON_pack_string ("exchange_url", @@ -352,85 +378,55 @@ TALER_MERCHANT_order_abort ( { GNUNET_break (0); json_decref (j_coins); - return NULL; + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } } abort_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_array_steal ("coins", j_coins), GNUNET_JSON_pack_data_auto ("h_contract", - h_contract)); - oah = GNUNET_new (struct TALER_MERCHANT_OrderAbortHandle); - oah->h_contract_terms = *h_contract; - oah->merchant_pub = *merchant_pub; - oah->ctx = ctx; - oah->abort_cb = cb; - oah->abort_cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/abort", - order_id); - oah->url = TALER_url_join (merchant_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == oah->url) + &poah->h_contract)); + eh = TALER_MERCHANT_curl_easy_get_ (poah->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&poah->post_ctx, + eh, + abort_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (abort_obj); - GNUNET_free (oah); - return NULL; - } - oah->num_coins = num_coins; - oah->coins = GNUNET_new_array (num_coins, - struct TALER_MERCHANT_AbortCoin); - GNUNET_memcpy (oah->coins, - coins, - num_coins * sizeof (struct TALER_MERCHANT_AbortCoin)); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (oah->url); - if (GNUNET_OK != - TALER_curl_easy_post (&oah->post_ctx, - eh, - abort_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (abort_obj); - GNUNET_free (oah); - return NULL; - } - json_decref (abort_obj); - oah->job = GNUNET_CURL_job_add2 (ctx, - eh, - oah->post_ctx.headers, - &handle_abort_finished, - oah); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return oah; + json_decref (abort_obj); + poah->job = GNUNET_CURL_job_add2 (poah->ctx, + eh, + poah->post_ctx.headers, + &handle_abort_finished, + poah); + if (NULL == poah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_order_abort_cancel ( - struct TALER_MERCHANT_OrderAbortHandle *oah) +TALER_MERCHANT_post_orders_abort_cancel ( + struct TALER_MERCHANT_PostOrdersAbortHandle *poah) { - if (NULL != oah->job) + if (NULL != poah->job) { - GNUNET_CURL_job_cancel (oah->job); - oah->job = NULL; + GNUNET_CURL_job_cancel (poah->job); + poah->job = NULL; } - TALER_curl_easy_post_finished (&oah->post_ctx); - GNUNET_free (oah->coins); - GNUNET_free (oah->url); - GNUNET_free (oah); + TALER_curl_easy_post_finished (&poah->post_ctx); + GNUNET_free (poah->coins); + GNUNET_free (poah->order_id); + GNUNET_free (poah->url); + GNUNET_free (poah->base_url); + GNUNET_free (poah); } -/* end of merchant_api_post_order_abort.c */ +/* end of merchant_api_post-orders-ORDER_ID-abort-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-claim-new.c b/src/lib/merchant_api_post-orders-ORDER_ID-claim-new.c @@ -1,294 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-orders-ORDER_ID-claim-new.c - * @brief Implementation of the POST /orders/$ID/claim request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-claim-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> -#include <taler/taler_signatures.h> - - -/** - * Handle for a POST /orders/$ORDER_ID/claim operation. - */ -struct TALER_MERCHANT_PostOrdersClaimHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostOrdersClaimCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order identifier. - */ - char *order_id; - - /** - * Wallet nonce for claiming. - */ - struct GNUNET_CRYPTO_EddsaPublicKey nonce; - - /** - * Optional claim token. - */ - const struct TALER_ClaimTokenP *token; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /orders/$ID/claim request. - * - * @param cls the `struct TALER_MERCHANT_PostOrdersClaimHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_order_claim_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostOrdersClaimHandle *poch = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostOrdersClaimResponse ocr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_object_const ( - "contract_terms", - &ocr.details.ok.contract_terms), - GNUNET_JSON_spec_fixed_auto ( - "sig", - &ocr.details.ok.merchant_sig), - GNUNET_JSON_spec_end () - }; - - poch->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /orders/$ID/claim completed with response code %u\n", - (unsigned int) response_code); - - if (MHD_HTTP_OK != response_code) - { - ocr.hr.ec = TALER_JSON_get_error_code (json); - ocr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Claim order failed with HTTP status code %u/%d\n", - (unsigned int) response_code, - (int) ocr.hr.ec); - poch->cb (poch->cb_cls, - &ocr); - TALER_MERCHANT_post_orders_claim_cancel (poch); - return; - } - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Claiming order failed: could not parse JSON response\n"); - GNUNET_break_op (0); - ocr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - ocr.hr.http_status = 0; - poch->cb (poch->cb_cls, - &ocr); - TALER_MERCHANT_post_orders_claim_cancel (poch); - return; - } - - if (GNUNET_OK != - TALER_JSON_contract_hash (ocr.details.ok.contract_terms, - &ocr.details.ok.h_contract_terms)) - { - GNUNET_break (0); - ocr.hr.ec = TALER_EC_MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE; - ocr.hr.http_status = 0; - GNUNET_JSON_parse_free (spec); - poch->cb (poch->cb_cls, - &ocr); - TALER_MERCHANT_post_orders_claim_cancel (poch); - return; - } - - poch->cb (poch->cb_cls, - &ocr); - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_post_orders_claim_cancel (poch); -} - - -struct TALER_MERCHANT_PostOrdersClaimHandle * -TALER_MERCHANT_post_orders_claim_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct GNUNET_CRYPTO_EddsaPublicKey *nonce) -{ - struct TALER_MERCHANT_PostOrdersClaimHandle *poch; - - poch = GNUNET_new (struct TALER_MERCHANT_PostOrdersClaimHandle); - poch->ctx = ctx; - poch->base_url = GNUNET_strdup (url); - poch->order_id = GNUNET_strdup (order_id); - poch->nonce = *nonce; - return poch; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_orders_claim_set_options_ ( - struct TALER_MERCHANT_PostOrdersClaimHandle *poch, - unsigned int num_options, - const struct TALER_MERCHANT_PostOrdersClaimOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN: - poch->token = options[i].details.token; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_claim_start ( - struct TALER_MERCHANT_PostOrdersClaimHandle *poch, - TALER_MERCHANT_PostOrdersClaimCallback cb, - TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - poch->cb = cb; - poch->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/claim", - poch->order_id); - poch->url = TALER_url_join (poch->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == poch->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("nonce", - &poch->nonce), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_data_auto ("token", - poch->token))); - eh = TALER_MERCHANT_curl_easy_get_ (poch->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&poch->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - poch->job = GNUNET_CURL_job_add2 (poch->ctx, - eh, - poch->post_ctx.headers, - &handle_post_order_claim_finished, - poch); - if (NULL == poch->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_orders_claim_cancel ( - struct TALER_MERCHANT_PostOrdersClaimHandle *poch) -{ - if (NULL != poch->job) - { - GNUNET_CURL_job_cancel (poch->job); - poch->job = NULL; - } - TALER_curl_easy_post_finished (&poch->post_ctx); - GNUNET_free (poch->order_id); - GNUNET_free (poch->url); - GNUNET_free (poch->base_url); - GNUNET_free (poch); -} - - -/* end of merchant_api_post-orders-ORDER_ID-claim-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-claim.c b/src/lib/merchant_api_post-orders-ORDER_ID-claim.c @@ -1,26 +1,25 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1, or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of + TALER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with TALER; see the file COPYING.LGPL. If not, - see <http://www.gnu.org/licenses/> + You should have received a copy of the GNU Lesser General + Public License along with TALER; see the file COPYING.LGPL. + If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-orders-ORDER_ID-claim.c - * @brief Implementation of POST /orders/$ID/claim + * @file merchant_api_post-orders-ORDER_ID-claim-new.c + * @brief Implementation of the POST /orders/$ID/claim request * @author Christian Grothoff - * @author Marcello Stanisci */ #include "taler/platform.h" #include <curl/curl.h> @@ -28,20 +27,26 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-orders-ORDER_ID-claim.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> +#include <taler/taler_signatures.h> /** - * Structure representing a POST /orders/$ID/claim operation. + * Handle for a POST /orders/$ORDER_ID/claim operation. */ -struct TALER_MERCHANT_OrderClaimHandle +struct TALER_MERCHANT_PostOrdersClaimHandle { /** - * Full URL, includes "/orders/$ID/claim". + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -53,12 +58,12 @@ struct TALER_MERCHANT_OrderClaimHandle /** * Function to call with the result. */ - TALER_MERCHANT_OrderClaimCallback cb; + TALER_MERCHANT_PostOrdersClaimCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -69,25 +74,40 @@ struct TALER_MERCHANT_OrderClaimHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Order identifier. + */ + char *order_id; + + /** + * Wallet nonce for claiming. + */ + struct GNUNET_CRYPTO_EddsaPublicKey nonce; + + /** + * Optional claim token. + */ + const struct TALER_ClaimTokenP *token; }; /** * Function called when we're done processing the - * POST /orders/$ID/claim request. + * HTTP POST /orders/$ID/claim request. * - * @param cls the `struct TALER_MERCHANT_OrderClaimHandle` + * @param cls the `struct TALER_MERCHANT_PostOrdersClaimHandle` * @param response_code HTTP response code, 0 on error - * @param response response body, should be NULL + * @param response response body, NULL if not in JSON */ static void handle_post_order_claim_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrderClaimHandle *och = cls; + struct TALER_MERCHANT_PostOrdersClaimHandle *poch = cls; const json_t *json = response; - struct TALER_MERCHANT_OrderClaimResponse ocr = { + struct TALER_MERCHANT_PostOrdersClaimResponse ocr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; @@ -97,13 +117,13 @@ handle_post_order_claim_finished (void *cls, &ocr.details.ok.contract_terms), GNUNET_JSON_spec_fixed_auto ( "sig", - &ocr.details.ok.sig), + &ocr.details.ok.merchant_sig), GNUNET_JSON_spec_end () }; - och->job = NULL; + poch->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Order claimed with status %u\n", + "POST /orders/$ID/claim completed with response code %u\n", (unsigned int) response_code); if (MHD_HTTP_OK != response_code) @@ -111,12 +131,12 @@ handle_post_order_claim_finished (void *cls, ocr.hr.ec = TALER_JSON_get_error_code (json); ocr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Proposal lookup failed with HTTP status code %u/%d\n", + "Claim order failed with HTTP status code %u/%d\n", (unsigned int) response_code, (int) ocr.hr.ec); - och->cb (och->cb_cls, - &ocr); - TALER_MERCHANT_order_claim_cancel (och); + poch->cb (poch->cb_cls, + &ocr); + TALER_MERCHANT_post_orders_claim_cancel (poch); return; } @@ -130,9 +150,9 @@ handle_post_order_claim_finished (void *cls, GNUNET_break_op (0); ocr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; ocr.hr.http_status = 0; - och->cb (och->cb_cls, - &ocr); - TALER_MERCHANT_order_claim_cancel (och); + poch->cb (poch->cb_cls, + &ocr); + TALER_MERCHANT_post_orders_claim_cancel (poch); return; } @@ -144,99 +164,131 @@ handle_post_order_claim_finished (void *cls, ocr.hr.ec = TALER_EC_MERCHANT_POST_ORDERS_ID_CLAIM_CLIENT_INTERNAL_FAILURE; ocr.hr.http_status = 0; GNUNET_JSON_parse_free (spec); - och->cb (och->cb_cls, - &ocr); - TALER_MERCHANT_order_claim_cancel (och); + poch->cb (poch->cb_cls, + &ocr); + TALER_MERCHANT_post_orders_claim_cancel (poch); return; } - och->cb (och->cb_cls, - &ocr); + + poch->cb (poch->cb_cls, + &ocr); GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_order_claim_cancel (och); + TALER_MERCHANT_post_orders_claim_cancel (poch); } -struct TALER_MERCHANT_OrderClaimHandle * -TALER_MERCHANT_order_claim (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, - const struct TALER_ClaimTokenP *claim_token, - TALER_MERCHANT_OrderClaimCallback cb, - void *cb_cls) +struct TALER_MERCHANT_PostOrdersClaimHandle * +TALER_MERCHANT_post_orders_claim_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct GNUNET_CRYPTO_EddsaPublicKey *nonce) { - struct TALER_MERCHANT_OrderClaimHandle *och; - json_t *req_obj; + struct TALER_MERCHANT_PostOrdersClaimHandle *poch; - if (NULL == order_id) + poch = GNUNET_new (struct TALER_MERCHANT_PostOrdersClaimHandle); + poch->ctx = ctx; + poch->base_url = GNUNET_strdup (url); + poch->order_id = GNUNET_strdup (order_id); + poch->nonce = *nonce; + return poch; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_orders_claim_set_options_ ( + struct TALER_MERCHANT_PostOrdersClaimHandle *poch, + unsigned int num_options, + const struct TALER_MERCHANT_PostOrdersClaimOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) { - GNUNET_break (0); - return NULL; + switch (options[i].option) + { + case TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_ORDERS_CLAIM_OPTION_TOKEN: + poch->token = options[i].details.token; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } } - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("nonce", - nonce), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_data_auto ("token", - claim_token))); - och = GNUNET_new (struct TALER_MERCHANT_OrderClaimHandle); - och->ctx = ctx; - och->cb = cb; - och->cb_cls = cb_cls; + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_claim_start ( + struct TALER_MERCHANT_PostOrdersClaimHandle *poch, + TALER_MERCHANT_PostOrdersClaimCallback cb, + TALER_MERCHANT_POST_ORDERS_CLAIM_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + + poch->cb = cb; + poch->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "orders/%s/claim", - order_id); - och->url = TALER_url_join (backend_url, - path, - NULL); + poch->order_id); + poch->url = TALER_url_join (poch->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == och->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (och); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Claiming order at %s\n", - och->url); + if (NULL == poch->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("nonce", + &poch->nonce), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_data_auto ("token", + poch->token))); + eh = TALER_MERCHANT_curl_easy_get_ (poch->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&poch->post_ctx, + eh, + req_obj)) ) { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (och->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&och->post_ctx, - eh, - req_obj)); + GNUNET_break (0); json_decref (req_obj); - och->job = GNUNET_CURL_job_add2 (ctx, - eh, - och->post_ctx.headers, - &handle_post_order_claim_finished, - och); - GNUNET_assert (NULL != och->job); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return och; + json_decref (req_obj); + poch->job = GNUNET_CURL_job_add2 (poch->ctx, + eh, + poch->post_ctx.headers, + &handle_post_order_claim_finished, + poch); + if (NULL == poch->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_order_claim_cancel (struct TALER_MERCHANT_OrderClaimHandle *och) +TALER_MERCHANT_post_orders_claim_cancel ( + struct TALER_MERCHANT_PostOrdersClaimHandle *poch) { - if (NULL != och->job) + if (NULL != poch->job) { - GNUNET_CURL_job_cancel (och->job); - och->job = NULL; + GNUNET_CURL_job_cancel (poch->job); + poch->job = NULL; } - TALER_curl_easy_post_finished (&och->post_ctx); - GNUNET_free (och->url); - GNUNET_free (och); + TALER_curl_easy_post_finished (&poch->post_ctx); + GNUNET_free (poch->order_id); + GNUNET_free (poch->url); + GNUNET_free (poch->base_url); + GNUNET_free (poch); } -/* end of merchant_api_post_order_claim.c */ +/* end of merchant_api_post-orders-ORDER_ID-claim-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-paid-new.c b/src/lib/merchant_api_post-orders-ORDER_ID-paid-new.c @@ -1,298 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-orders-ORDER_ID-paid-new.c - * @brief Implementation of the POST /orders/$ORDER_ID/paid request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-paid-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> -#include <taler/taler_signatures.h> - - -/** - * Handle for a POST /orders/$ORDER_ID/paid operation. - */ -struct TALER_MERCHANT_PostOrdersPaidHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostOrdersPaidCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order identifier. - */ - char *order_id; - - /** - * Session identifier. - */ - char *session_id; - - /** - * Hash of the contract terms. - */ - struct TALER_PrivateContractHashP h_contract_terms; - - /** - * Merchant signature over the session data. - */ - struct TALER_MerchantSignatureP merchant_sig; - - /** - * Optional hash of wallet-specific data. - */ - const struct GNUNET_HashCode *wallet_data_hash; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /orders/$ORDER_ID/paid request. - * - * @param cls the `struct TALER_MERCHANT_PostOrdersPaidHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_paid_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostOrdersPaidHandle *poph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostOrdersPaidResponse opr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - poph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /orders/$ID/paid completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - break; - case MHD_HTTP_BAD_REQUEST: - opr.hr.ec = TALER_JSON_get_error_code (json); - opr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - opr.hr.ec = TALER_JSON_get_error_code (json); - opr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - opr.hr.ec = TALER_JSON_get_error_code (json); - opr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - opr.hr.ec = TALER_JSON_get_error_code (json); - opr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - opr.hr.ec = TALER_JSON_get_error_code (json); - opr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_SERVICE_UNAVAILABLE: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &opr.hr); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &opr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) opr.hr.ec); - GNUNET_break_op (0); - break; - } - poph->cb (poph->cb_cls, - &opr); - TALER_MERCHANT_post_orders_paid_cancel (poph); -} - - -struct TALER_MERCHANT_PostOrdersPaidHandle * -TALER_MERCHANT_post_orders_paid_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const char *session_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_MerchantSignatureP *merchant_sig) -{ - struct TALER_MERCHANT_PostOrdersPaidHandle *poph; - - poph = GNUNET_new (struct TALER_MERCHANT_PostOrdersPaidHandle); - poph->ctx = ctx; - poph->base_url = GNUNET_strdup (url); - poph->order_id = GNUNET_strdup (order_id); - poph->session_id = GNUNET_strdup (session_id); - poph->h_contract_terms = *h_contract_terms; - poph->merchant_sig = *merchant_sig; - return poph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_orders_paid_set_options_ ( - struct TALER_MERCHANT_PostOrdersPaidHandle *poph, - unsigned int num_options, - const struct TALER_MERCHANT_PostOrdersPaidOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_ORDERS_PAID_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH: - poph->wallet_data_hash = options[i].details.wallet_data_hash; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_paid_start ( - struct TALER_MERCHANT_PostOrdersPaidHandle *poph, - TALER_MERCHANT_PostOrdersPaidCallback cb, - TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - poph->cb = cb; - poph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/paid", - poph->order_id); - poph->url = TALER_url_join (poph->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == poph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("sig", - &poph->merchant_sig), - GNUNET_JSON_pack_data_auto ("h_contract", - &poph->h_contract_terms), - GNUNET_JSON_pack_string ("session_id", - poph->session_id)); - eh = TALER_MERCHANT_curl_easy_get_ (poph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&poph->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - poph->job = GNUNET_CURL_job_add2 (poph->ctx, - eh, - poph->post_ctx.headers, - &handle_paid_finished, - poph); - if (NULL == poph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_orders_paid_cancel ( - struct TALER_MERCHANT_PostOrdersPaidHandle *poph) -{ - if (NULL != poph->job) - { - GNUNET_CURL_job_cancel (poph->job); - poph->job = NULL; - } - TALER_curl_easy_post_finished (&poph->post_ctx); - GNUNET_free (poph->order_id); - GNUNET_free (poph->session_id); - GNUNET_free (poph->url); - GNUNET_free (poph->base_url); - GNUNET_free (poph); -} - - -/* end of merchant_api_post-orders-ORDER_ID-paid-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-paid.c b/src/lib/merchant_api_post-orders-ORDER_ID-paid.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2021 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,10 +17,9 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-orders-ORDER_ID-paid.c - * @brief Implementation of the POST /order/$ID/paid request - * of the merchant's HTTP API - * @author Jonathan Buchanan + * @file merchant_api_post-orders-ORDER_ID-paid-new.c + * @brief Implementation of the POST /orders/$ORDER_ID/paid request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -28,23 +27,26 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-orders-ORDER_ID-paid.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> -#include <taler/taler_exchange_service.h> #include <taler/taler_curl_lib.h> +#include <taler/taler_signatures.h> /** - * @brief Handle to a POST /orders/$ID/paid operation at a merchant. + * Handle for a POST /orders/$ORDER_ID/paid operation. */ -struct TALER_MERCHANT_OrderPaidHandle +struct TALER_MERCHANT_PostOrdersPaidHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -56,12 +58,12 @@ struct TALER_MERCHANT_OrderPaidHandle /** * Function to call with the result. */ - TALER_MERCHANT_OrderPaidCallback paid_cb; + TALER_MERCHANT_PostOrdersPaidCallback cb; /** - * Closure for @a paid_cb. + * Closure for @a cb. */ - void *paid_cb_cls; + TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -72,14 +74,39 @@ struct TALER_MERCHANT_OrderPaidHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Order identifier. + */ + char *order_id; + + /** + * Session identifier. + */ + char *session_id; + + /** + * Hash of the contract terms. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Merchant signature over the session data. + */ + struct TALER_MerchantSignatureP merchant_sig; + + /** + * Optional hash of wallet-specific data. + */ + const struct GNUNET_HashCode *wallet_data_hash; }; /** * Function called when we're done processing the - * HTTP /paid request. + * HTTP POST /orders/$ORDER_ID/paid request. * - * @param cls the `struct TALER_MERCHANT_OrderPaidHandle` + * @param cls the `struct TALER_MERCHANT_PostOrdersPaidHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -88,16 +115,16 @@ handle_paid_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrderPaidHandle *oph = cls; + struct TALER_MERCHANT_PostOrdersPaidHandle *poph = cls; const json_t *json = response; - struct TALER_MERCHANT_OrderPaidResponse opr = { + struct TALER_MERCHANT_PostOrdersPaidResponse opr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - oph->job = NULL; + poph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "/paid completed with response code %u\n", + "POST /orders/$ID/paid completed with response code %u\n", (unsigned int) response_code); switch (response_code) { @@ -105,69 +132,36 @@ handle_paid_finished (void *cls, opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: - { - bool refunded; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_bool ("refunded", - &refunded), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (opr.hr.reply, - spec, - NULL, - NULL)) - { - GNUNET_break_op (0); - opr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - break; - } break; case MHD_HTTP_BAD_REQUEST: opr.hr.ec = TALER_JSON_get_error_code (json); opr.hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ break; case MHD_HTTP_FORBIDDEN: opr.hr.ec = TALER_JSON_get_error_code (json); opr.hr.hint = TALER_JSON_get_error_hint (json); - /* The signature provided was invalid */ break; case MHD_HTTP_NOT_FOUND: opr.hr.ec = TALER_JSON_get_error_code (json); opr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ break; case MHD_HTTP_CONFLICT: opr.hr.ec = TALER_JSON_get_error_code (json); opr.hr.hint = TALER_JSON_get_error_hint (json); - /* The hashed contract terms don't match with the order_id. */ break; case MHD_HTTP_INTERNAL_SERVER_ERROR: opr.hr.ec = TALER_JSON_get_error_code (json); opr.hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ break; case MHD_HTTP_SERVICE_UNAVAILABLE: TALER_MERCHANT_parse_error_details_ (json, response_code, &opr.hr); - /* Exchange couldn't respond properly; the retry is - left to the application */ break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, &opr.hr); - /* unexpected response code */ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, @@ -175,97 +169,130 @@ handle_paid_finished (void *cls, GNUNET_break_op (0); break; } - oph->paid_cb (oph->paid_cb_cls, - &opr); - TALER_MERCHANT_order_paid_cancel (oph); + poph->cb (poph->cb_cls, + &opr); + TALER_MERCHANT_post_orders_paid_cancel (poph); } -struct TALER_MERCHANT_OrderPaidHandle * -TALER_MERCHANT_order_paid ( +struct TALER_MERCHANT_PostOrdersPaidHandle * +TALER_MERCHANT_post_orders_paid_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, + const char *url, const char *order_id, const char *session_id, const struct TALER_PrivateContractHashP *h_contract_terms, - const struct GNUNET_HashCode *wallet_data_hash, - const struct TALER_MerchantSignatureP *merchant_sig, - TALER_MERCHANT_OrderPaidCallback paid_cb, - void *paid_cb_cls) + const struct TALER_MerchantSignatureP *merchant_sig) +{ + struct TALER_MERCHANT_PostOrdersPaidHandle *poph; + + poph = GNUNET_new (struct TALER_MERCHANT_PostOrdersPaidHandle); + poph->ctx = ctx; + poph->base_url = GNUNET_strdup (url); + poph->order_id = GNUNET_strdup (order_id); + poph->session_id = GNUNET_strdup (session_id); + poph->h_contract_terms = *h_contract_terms; + poph->merchant_sig = *merchant_sig; + return poph; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_orders_paid_set_options_ ( + struct TALER_MERCHANT_PostOrdersPaidHandle *poph, + unsigned int num_options, + const struct TALER_MERCHANT_PostOrdersPaidOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_ORDERS_PAID_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_ORDERS_PAID_OPTION_WALLET_DATA_HASH: + poph->wallet_data_hash = options[i].details.wallet_data_hash; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_paid_start ( + struct TALER_MERCHANT_PostOrdersPaidHandle *poph, + TALER_MERCHANT_PostOrdersPaidCallback cb, + TALER_MERCHANT_POST_ORDERS_PAID_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderPaidHandle *oph; json_t *req_obj; + CURL *eh; - (void) wallet_data_hash; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("sig", - merchant_sig), - GNUNET_JSON_pack_data_auto ("h_contract", - h_contract_terms), - GNUNET_JSON_pack_string ("session_id", - session_id)); - oph = GNUNET_new (struct TALER_MERCHANT_OrderPaidHandle); - oph->ctx = ctx; - oph->paid_cb = paid_cb; - oph->paid_cb_cls = paid_cb_cls; + poph->cb = cb; + poph->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "orders/%s/paid", - order_id); - oph->url = TALER_url_join (merchant_url, - path, - NULL); + poph->order_id); + poph->url = TALER_url_join (poph->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == oph->url) + if (NULL == poph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("sig", + &poph->merchant_sig), + GNUNET_JSON_pack_data_auto ("h_contract", + &poph->h_contract_terms), + GNUNET_JSON_pack_string ("session_id", + poph->session_id)); + eh = TALER_MERCHANT_curl_easy_get_ (poph->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&poph->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (oph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (oph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&oph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (oph); - return NULL; - } - json_decref (req_obj); - oph->job = GNUNET_CURL_job_add2 (ctx, - eh, - oph->post_ctx.headers, - &handle_paid_finished, - oph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return oph; + json_decref (req_obj); + poph->job = GNUNET_CURL_job_add2 (poph->ctx, + eh, + poph->post_ctx.headers, + &handle_paid_finished, + poph); + if (NULL == poph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_order_paid_cancel ( - struct TALER_MERCHANT_OrderPaidHandle *oph) +TALER_MERCHANT_post_orders_paid_cancel ( + struct TALER_MERCHANT_PostOrdersPaidHandle *poph) { - if (NULL != oph->job) + if (NULL != poph->job) { - GNUNET_CURL_job_cancel (oph->job); - oph->job = NULL; + GNUNET_CURL_job_cancel (poph->job); + poph->job = NULL; } - TALER_curl_easy_post_finished (&oph->post_ctx); - GNUNET_free (oph->url); - GNUNET_free (oph); + TALER_curl_easy_post_finished (&poph->post_ctx); + GNUNET_free (poph->order_id); + GNUNET_free (poph->session_id); + GNUNET_free (poph->url); + GNUNET_free (poph->base_url); + GNUNET_free (poph); } -/* end of merchant_api_post_order_paid.c */ +/* end of merchant_api_post-orders-ORDER_ID-paid-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-pay-new.c b/src/lib/merchant_api_post-orders-ORDER_ID-pay-new.c @@ -1,1123 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-orders-ORDER_ID-pay-new.c - * @brief Implementation of the POST /orders/$ORDER_ID/pay request - * @author Christian Grothoff - * @author Marcello Stanisci - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-pay-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> -#include <taler/taler_signatures.h> -#if HAVE_DONAU_DONAU_SERVICE_H -#include <donau/donau_service.h> -#include <donau/donau_json_lib.h> -#endif - -/** - * Handle for a POST /orders/$ORDER_ID/pay operation. - */ -struct TALER_MERCHANT_PostOrdersPayHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostOrdersPayCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order identifier. - */ - char *order_id; - - /** - * The coins we are paying with (frontend mode, already signed). - */ - struct TALER_MERCHANT_PostOrdersPayPaidCoin *paid_coins; - - /** - * Number of @e paid_coins. - */ - unsigned int num_paid_coins; - - /** - * Hash of the contract terms (wallet mode). - */ - struct TALER_PrivateContractHashP h_contract_terms; - - /** - * Public key of the merchant (wallet mode). - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Merchant signature (wallet mode). - */ - struct TALER_MerchantSignatureP merchant_sig; - - /** - * Total payment amount (wallet mode). - */ - struct TALER_Amount amount; - - /** - * Maximum fee (wallet mode). - */ - struct TALER_Amount max_fee; - - /** - * Contract timestamp (wallet mode). - */ - struct GNUNET_TIME_Timestamp timestamp; - - /** - * Refund deadline (wallet mode). - */ - struct GNUNET_TIME_Timestamp refund_deadline; - - /** - * Payment deadline (wallet mode). - */ - struct GNUNET_TIME_Timestamp pay_deadline; - - /** - * Hash of merchant wire details (wallet mode). - */ - struct TALER_MerchantWireHashP h_wire; - - /** - * Choice index (wallet mode). - */ - int choice_index; - - /** - * Coins with private keys (wallet mode). - */ - struct TALER_MERCHANT_PostOrdersPayCoin *coins; - - /** - * Number of @e coins (wallet mode). - */ - unsigned int num_coins; - - /** - * Optional session identifier. - */ - char *session_id; - - /** - * Optional wallet data (JSON). - */ - json_t *wallet_data; - - /** - * Used tokens (public form, frontend mode). - */ - struct TALER_MERCHANT_PostOrdersPayUsedToken *used_tokens; - - /** - * Number of @e used_tokens. - */ - unsigned int num_used_tokens; - - /** - * Use tokens (private form, wallet mode). - */ - struct TALER_MERCHANT_PostOrdersPayUseToken *use_tokens; - - /** - * Number of @e use_tokens. - */ - unsigned int num_use_tokens; - - /** - * Output tokens (wallet mode). - */ - struct TALER_MERCHANT_PostOrdersPayOutputToken *output_tokens; - - /** - * Number of @e output_tokens. - */ - unsigned int num_output_tokens; - - /** - * Output tokens as JSON array (frontend mode). - */ - json_t *output_tokens_json; - - /** - * Base URL of the selected donau for donation receipts. - */ - char *donau_url; - - /** - * Tax year used for the donau. - */ - unsigned int donau_year; - - /** - * Array of blinded donation receipts. - */ - struct DONAU_BlindedUniqueDonorIdentifierKeyPair *donau_bkps; - - /** - * Length of the @e donau_bkps array. - */ - size_t num_donau_bkps; - - /** - * Set to true if this is the wallet mode (private keys available). - */ - bool am_wallet; -}; - - -/** - * Parse blindly signed output tokens from JSON response. - * - * @param token_sigs the JSON array with the token signatures, can be NULL - * @param[out] tokens where to store the parsed tokens - * @param[out] num_tokens where to store the length of the @a tokens array - * @return #GNUNET_YES on success - */ -static enum GNUNET_GenericReturnValue -parse_tokens (const json_t *token_sigs, - struct TALER_MERCHANT_PostOrdersPayOutputToken **tokens, - unsigned int *num_tokens) -{ - GNUNET_array_grow (*tokens, - *num_tokens, - json_array_size (token_sigs)); - - for (unsigned int i = 0; i < (*num_tokens); i++) - { - struct TALER_MERCHANT_PostOrdersPayOutputToken *token = &(*tokens)[i]; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_blinded_token_issue_sig ("blind_sig", - &token->blinded_sig), - GNUNET_JSON_spec_end () - }; - const json_t *jtoken - = json_array_get (token_sigs, - i); - - if (NULL == jtoken) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_JSON_parse (jtoken, - spec, - NULL, NULL)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - - return GNUNET_YES; -} - - -/** - * Function called when we're done processing the - * HTTP POST /orders/$ORDER_ID/pay request. - * - * @param cls the `struct TALER_MERCHANT_PostOrdersPayHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_pay_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostOrdersPayHandle *poph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostOrdersPayResponse pr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - poph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /orders/$ID/pay completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - if (poph->am_wallet) - { - const json_t *token_sigs = NULL; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", - &pr.details.ok.merchant_sig), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("pos_confirmation", - &pr.details.ok.pos_confirmation), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ("token_sigs", - &token_sigs), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - pr.hr.http_status = 0; - pr.hr.hint = "sig field missing in response"; - break; - } - - if (GNUNET_OK != - parse_tokens (token_sigs, - &pr.details.ok.tokens, - &pr.details.ok.num_tokens)) - { - GNUNET_break_op (0); - pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - pr.hr.http_status = 0; - pr.hr.hint = "failed to parse token_sigs field in response"; - break; - } - - if (GNUNET_OK != - TALER_merchant_pay_verify (&poph->h_contract_terms, - &poph->merchant_pub, - &pr.details.ok.merchant_sig)) - { - GNUNET_break_op (0); - pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - pr.hr.http_status = 0; - pr.hr.hint = "signature invalid"; - } - } - break; - case MHD_HTTP_NOT_ACCEPTABLE: - pr.hr.ec = TALER_JSON_get_error_code (json); - pr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_BAD_REQUEST: - pr.hr.ec = TALER_JSON_get_error_code (json); - pr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_PAYMENT_REQUIRED: - pr.hr.ec = TALER_JSON_get_error_code (json); - pr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - pr.hr.ec = TALER_JSON_get_error_code (json); - pr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - pr.hr.ec = TALER_JSON_get_error_code (json); - pr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_REQUEST_TIMEOUT: - pr.hr.ec = TALER_JSON_get_error_code (json); - pr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - TALER_MERCHANT_parse_error_details_ (json, - MHD_HTTP_CONFLICT, - &pr.hr); - break; - case MHD_HTTP_GONE: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - break; - case MHD_HTTP_PRECONDITION_FAILED: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - break; - case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: - { - json_t *ebus = json_object_get (json, - "exchange_base_urls"); - if (NULL == ebus) - { - GNUNET_break_op (0); - pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - pr.hr.http_status = 0; - pr.hr.hint - = "failed to parse exchange_base_urls field in response"; - break; - } - { - size_t alen = json_array_size (ebus); - const char *ebua[GNUNET_NZL (alen)]; - size_t idx; - json_t *jebu; - bool ok = true; - - GNUNET_assert (alen <= UINT_MAX); - json_array_foreach (ebus, idx, jebu) - { - ebua[idx] = json_string_value (jebu); - if (NULL == ebua[idx]) - { - GNUNET_break_op (0); - pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - pr.hr.http_status = 0; - pr.hr.hint - = "non-string value in exchange_base_urls in response"; - ok = false; - break; - } - } - if (! ok) - break; - pr.details.unavailable_for_legal_reasons.num_exchanges - = (unsigned int) alen; - pr.details.unavailable_for_legal_reasons.exchanges - = ebua; - poph->cb (poph->cb_cls, - &pr); - TALER_MERCHANT_post_orders_pay_cancel (poph); - return; - } - } - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - break; - case MHD_HTTP_BAD_GATEWAY: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - break; - case MHD_HTTP_SERVICE_UNAVAILABLE: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - break; - case MHD_HTTP_GATEWAY_TIMEOUT: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pr.hr.ec); - GNUNET_break_op (0); - break; - } - poph->cb (poph->cb_cls, - &pr); - TALER_MERCHANT_post_orders_pay_cancel (poph); -} - - -struct TALER_MERCHANT_PostOrdersPayHandle * -TALER_MERCHANT_post_orders_pay_frontend_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - unsigned int num_coins, - const struct TALER_MERCHANT_PostOrdersPayPaidCoin coins[static num_coins]) -{ - struct TALER_MERCHANT_PostOrdersPayHandle *poph; - - poph = GNUNET_new (struct TALER_MERCHANT_PostOrdersPayHandle); - poph->ctx = ctx; - poph->base_url = GNUNET_strdup (url); - poph->order_id = GNUNET_strdup (order_id); - poph->am_wallet = false; - poph->num_paid_coins = num_coins; - poph->paid_coins = GNUNET_new_array ( - num_coins, - struct TALER_MERCHANT_PostOrdersPayPaidCoin); - for (unsigned int i = 0; i < num_coins; i++) - { - struct TALER_MERCHANT_PostOrdersPayPaidCoin *dst = &poph->paid_coins[i]; - const struct TALER_MERCHANT_PostOrdersPayPaidCoin *src = &coins[i]; - - *dst = *src; - /* deep copy fields that need it */ - TALER_denom_pub_copy (&dst->denom_pub, - &src->denom_pub); - TALER_denom_sig_copy (&dst->denom_sig, - &src->denom_sig); - dst->exchange_url = GNUNET_strdup (src->exchange_url); - } - return poph; -} - - -struct TALER_MERCHANT_PostOrdersPayHandle * -TALER_MERCHANT_post_orders_pay_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - int choice_index, - const struct TALER_Amount *amount, - const struct TALER_Amount *max_fee, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_MerchantSignatureP *merchant_sig, - struct GNUNET_TIME_Timestamp timestamp, - struct GNUNET_TIME_Timestamp refund_deadline, - struct GNUNET_TIME_Timestamp pay_deadline, - const struct TALER_MerchantWireHashP *h_wire, - unsigned int num_coins, - const struct TALER_MERCHANT_PostOrdersPayCoin coins[static num_coins]) -{ - struct TALER_MERCHANT_PostOrdersPayHandle *poph; - - if (GNUNET_YES != - TALER_amount_cmp_currency (amount, - max_fee)) - { - GNUNET_break (0); - return NULL; - } - - poph = GNUNET_new (struct TALER_MERCHANT_PostOrdersPayHandle); - poph->ctx = ctx; - poph->base_url = GNUNET_strdup (url); - poph->order_id = GNUNET_strdup (order_id); - poph->am_wallet = true; - poph->h_contract_terms = *h_contract_terms; - poph->choice_index = choice_index; - poph->amount = *amount; - poph->max_fee = *max_fee; - poph->merchant_pub = *merchant_pub; - poph->merchant_sig = *merchant_sig; - poph->timestamp = timestamp; - poph->refund_deadline = refund_deadline; - poph->pay_deadline = pay_deadline; - poph->h_wire = *h_wire; - poph->num_coins = num_coins; - poph->coins = GNUNET_new_array (num_coins, - struct TALER_MERCHANT_PostOrdersPayCoin); - for (unsigned int i = 0; i < num_coins; i++) - { - struct TALER_MERCHANT_PostOrdersPayCoin *dst = &poph->coins[i]; - const struct TALER_MERCHANT_PostOrdersPayCoin *src = &coins[i]; - - *dst = *src; - TALER_denom_pub_copy (&dst->denom_pub, - &src->denom_pub); - TALER_denom_sig_copy (&dst->denom_sig, - &src->denom_sig); - dst->exchange_url = GNUNET_strdup (src->exchange_url); - } - return poph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_orders_pay_set_options_ ( - struct TALER_MERCHANT_PostOrdersPayHandle *poph, - unsigned int num_options, - const struct TALER_MERCHANT_PostOrdersPayOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID: - GNUNET_free (poph->session_id); - if (NULL != options[i].details.session_id) - poph->session_id = GNUNET_strdup (options[i].details.session_id); - break; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA: - json_decref (poph->wallet_data); - poph->wallet_data = NULL; - if (NULL != options[i].details.wallet_data) - poph->wallet_data = json_incref ( - (json_t *) options[i].details.wallet_data); - break; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS: - GNUNET_free (poph->used_tokens); - poph->num_used_tokens = options[i].details.used_tokens.num; - if (0 < poph->num_used_tokens) - { - poph->used_tokens = GNUNET_new_array ( - poph->num_used_tokens, - struct TALER_MERCHANT_PostOrdersPayUsedToken); - GNUNET_memcpy (poph->used_tokens, - options[i].details.used_tokens.tokens, - poph->num_used_tokens - * sizeof (struct TALER_MERCHANT_PostOrdersPayUsedToken)); - } - break; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS: - GNUNET_free (poph->use_tokens); - poph->num_use_tokens = options[i].details.use_tokens.num; - if (0 < poph->num_use_tokens) - { - poph->use_tokens = GNUNET_new_array ( - poph->num_use_tokens, - struct TALER_MERCHANT_PostOrdersPayUseToken); - GNUNET_memcpy (poph->use_tokens, - options[i].details.use_tokens.tokens, - poph->num_use_tokens - * sizeof (struct TALER_MERCHANT_PostOrdersPayUseToken)); - } - break; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS: - GNUNET_free (poph->output_tokens); - poph->num_output_tokens = options[i].details.output_tokens.num; - if (0 < poph->num_output_tokens) - { - poph->output_tokens = GNUNET_new_array ( - poph->num_output_tokens, - struct TALER_MERCHANT_PostOrdersPayOutputToken); - GNUNET_memcpy ( - poph->output_tokens, - options[i].details.output_tokens.tokens, - poph->num_output_tokens - * sizeof (struct TALER_MERCHANT_PostOrdersPayOutputToken)); - } - break; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON: - json_decref (poph->output_tokens_json); - poph->output_tokens_json = NULL; - if (NULL != options[i].details.output_tokens_json) - poph->output_tokens_json = json_incref ( - options[i].details.output_tokens_json); - break; - case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU: -#if HAVE_DONAU_DONAU_SERVICE_H - if (NULL != poph->donau_url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Only one set of donation receipts is allowed to be specified\n"); - return GNUNET_NO; - } - poph->donau_url - = GNUNET_strdup (options[i].details.output_donau.donau_base_url); - poph->donau_year - = options[i].details.output_donau.year; - poph->num_donau_bkps = options[i].details.output_donau.num_bkps; - poph->donau_bkps = GNUNET_new_array ( - poph->num_donau_bkps, - struct DONAU_BlindedUniqueDonorIdentifierKeyPair); - for (size_t j=0; j<poph->num_donau_bkps; j++) - { - const struct DONAU_BlindedUniqueDonorIdentifierKeyPair *src - = &options[i].details.output_donau.bkps[j]; - struct DONAU_BlindedUniqueDonorIdentifierKeyPair *dst - = &poph->donau_bkps[j]; - - dst->h_donation_unit_pub = src->h_donation_unit_pub; - dst->blinded_udi.blinded_message - = GNUNET_CRYPTO_blinded_message_incref ( - src->blinded_udi.blinded_message); - } - break; -#else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Donation receipts are not supported by this build!\n"); - return GNUNET_NO; -#endif - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_pay_start ( - struct TALER_MERCHANT_PostOrdersPayHandle *poph, - TALER_MERCHANT_PostOrdersPayCallback cb, - TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cb_cls) -{ - json_t *pay_obj; - json_t *j_coins; - json_t *j_tokens = NULL; - json_t *j_output_tokens = NULL; - CURL *eh; - - poph->cb = cb; - poph->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/pay", - poph->order_id); - poph->url = TALER_url_join (poph->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == poph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - - if (poph->am_wallet) - { - /* Wallet mode: sign coins and tokens, build wallet_data */ - json_t *wallet_data = poph->wallet_data; - json_t *j_donau_data = NULL; - struct GNUNET_HashCode wallet_data_hash; - - if (NULL != poph->donau_url) - { - json_t *budis; - - budis = json_array (); - GNUNET_assert (NULL != budis); - for (size_t i=0; i<poph->num_donau_bkps; i++) - { - const struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkp - = &poph->donau_bkps[i]; - json_t *budikeypair = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("h_donation_unit_pub", - &bkp->h_donation_unit_pub), - DONAU_JSON_pack_blinded_donation_identifier ("blinded_udi", - &bkp->blinded_udi)); - - GNUNET_assert (0 == - json_array_append_new (budis, - budikeypair)); - } - - j_donau_data = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("url", - poph->donau_url), - GNUNET_JSON_pack_int64 ("year", - poph->donau_year), - GNUNET_JSON_pack_array_steal ("budikeypairs", - budis)); - } - - /* Build output token envelopes JSON if we have output tokens */ - if (0 < poph->num_output_tokens) - { - j_output_tokens = json_array (); - GNUNET_assert (NULL != j_output_tokens); - for (unsigned int i = 0; i < poph->num_output_tokens; i++) - { - json_t *j_token_ev; - const struct TALER_MERCHANT_PostOrdersPayOutputToken *ev - = &poph->output_tokens[i]; - - j_token_ev = GNUNET_JSON_PACK ( - TALER_JSON_pack_token_envelope (NULL, - &ev->envelope)); - if (0 != - json_array_append_new (j_output_tokens, - j_token_ev)) - { - GNUNET_break (0); - json_decref (j_output_tokens); - json_decref (j_donau_data); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - } - else if (NULL != poph->output_tokens_json) - { - j_output_tokens = json_incref (poph->output_tokens_json); - } - - /* Build wallet_data if choice_index is valid */ - if (0 <= poph->choice_index) - { - if (NULL == wallet_data) - { - wallet_data = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_int64 ("choice_index", - poph->choice_index), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("donau", - j_donau_data)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_incref ("tokens_evs", - j_output_tokens))); - } - TALER_json_hash (wallet_data, - &wallet_data_hash); - } - json_decref (j_donau_data); - j_donau_data = NULL; - - if ( (0 < poph->num_use_tokens || 0 < poph->num_output_tokens - || NULL != poph->output_tokens_json) - && (0 > poph->choice_index) ) - { - GNUNET_break (0); - json_decref (j_output_tokens); - if ( (NULL == poph->wallet_data) && - (NULL != wallet_data) ) - json_decref (wallet_data); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - - /* Sign coins */ - j_coins = json_array (); - GNUNET_assert (NULL != j_coins); - for (unsigned int i = 0; i < poph->num_coins; i++) - { - const struct TALER_MERCHANT_PostOrdersPayCoin *coin = &poph->coins[i]; - struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_CoinSpendSignatureP coin_sig; - struct TALER_Amount fee; - struct TALER_DenominationHashP h_denom_pub; - json_t *j_coin; - - if (0 > - TALER_amount_subtract (&fee, - &coin->amount_with_fee, - &coin->amount_without_fee)) - { - GNUNET_break (0); - json_decref (j_coins); - json_decref (j_output_tokens); - if ( (NULL == poph->wallet_data) && - (NULL != wallet_data) ) - json_decref (wallet_data); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - TALER_denom_pub_hash (&coin->denom_pub, - &h_denom_pub); - TALER_wallet_deposit_sign (&coin->amount_with_fee, - &fee, - &poph->h_wire, - &poph->h_contract_terms, - (0 <= poph->choice_index) - ? &wallet_data_hash - : NULL, - GNUNET_is_zero (&coin->h_age_commitment) - ? NULL - : &coin->h_age_commitment, - NULL /* h_extensions */, - &h_denom_pub, - poph->timestamp, - &poph->merchant_pub, - poph->refund_deadline, - &coin->coin_priv, - &coin_sig); - GNUNET_CRYPTO_eddsa_key_get_public (&coin->coin_priv.eddsa_priv, - &coin_pub.eddsa_pub); - j_coin = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("contribution", - &coin->amount_with_fee), - GNUNET_JSON_pack_data_auto ("coin_pub", - &coin_pub), - GNUNET_JSON_pack_string ("exchange_url", - coin->exchange_url), - GNUNET_JSON_pack_data_auto ("h_denom", - &h_denom_pub), - TALER_JSON_pack_denom_sig ("ub_sig", - &coin->denom_sig), - GNUNET_JSON_pack_data_auto ("coin_sig", - &coin_sig)); - if (0 != - json_array_append_new (j_coins, - j_coin)) - { - GNUNET_break (0); - json_decref (j_coins); - json_decref (j_output_tokens); - if ( (NULL == poph->wallet_data) && - (NULL != wallet_data) ) - json_decref (wallet_data); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - - /* Sign use tokens */ - if (0 < poph->num_use_tokens) - { - j_tokens = json_array (); - GNUNET_assert (NULL != j_tokens); - for (unsigned int i = 0; i < poph->num_use_tokens; i++) - { - const struct TALER_MERCHANT_PostOrdersPayUseToken *token - = &poph->use_tokens[i]; - struct TALER_TokenUseSignatureP token_sig; - struct TALER_TokenUsePublicKeyP token_pub; - json_t *j_token; - - TALER_wallet_token_use_sign (&poph->h_contract_terms, - &wallet_data_hash, - &token->token_priv, - &token_sig); - GNUNET_CRYPTO_eddsa_key_get_public ( - &token->token_priv.private_key, - &token_pub.public_key); - j_token = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("token_sig", - &token_sig), - GNUNET_JSON_pack_data_auto ("token_pub", - &token_pub), - GNUNET_JSON_pack_data_auto ( - "h_issue", - &token->issue_pub.public_key->pub_key_hash), - TALER_JSON_pack_token_issue_sig ("ub_sig", - &token->ub_sig)); - if (0 != - json_array_append_new (j_tokens, - j_token)) - { - GNUNET_break (0); - json_decref (j_coins); - json_decref (j_tokens); - json_decref (j_output_tokens); - if ( (NULL == poph->wallet_data) && - (NULL != wallet_data) ) - json_decref (wallet_data); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - } - - pay_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("coins", - j_coins), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_steal ("tokens", - j_tokens)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("wallet_data", - wallet_data)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("session_id", - poph->session_id))); - if ( (NULL == poph->wallet_data) && - (NULL != wallet_data) ) - json_decref (wallet_data); - } - else - { - /* Frontend mode: coins are already signed */ - j_coins = json_array (); - GNUNET_assert (NULL != j_coins); - for (unsigned int i = 0; i < poph->num_paid_coins; i++) - { - const struct TALER_MERCHANT_PostOrdersPayPaidCoin *pc - = &poph->paid_coins[i]; - struct TALER_DenominationHashP denom_hash; - json_t *j_coin; - - TALER_denom_pub_hash (&pc->denom_pub, - &denom_hash); - j_coin = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("contribution", - &pc->amount_with_fee), - GNUNET_JSON_pack_data_auto ("coin_pub", - &pc->coin_pub), - GNUNET_JSON_pack_string ("exchange_url", - pc->exchange_url), - GNUNET_JSON_pack_data_auto ("h_denom", - &denom_hash), - TALER_JSON_pack_denom_sig ("ub_sig", - &pc->denom_sig), - GNUNET_JSON_pack_data_auto ("coin_sig", - &pc->coin_sig)); - if (0 != - json_array_append_new (j_coins, - j_coin)) - { - GNUNET_break (0); - json_decref (j_coins); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - - /* Build used tokens JSON (frontend mode) */ - if (0 < poph->num_used_tokens) - { - j_tokens = json_array (); - GNUNET_assert (NULL != j_tokens); - for (unsigned int i = 0; i < poph->num_used_tokens; i++) - { - const struct TALER_MERCHANT_PostOrdersPayUsedToken *ut - = &poph->used_tokens[i]; - json_t *j_token; - - j_token = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("token_sig", - &ut->token_sig), - GNUNET_JSON_pack_data_auto ("token_pub", - &ut->token_pub), - GNUNET_JSON_pack_data_auto ( - "h_issue", - &ut->issue_pub.public_key->pub_key_hash), - TALER_JSON_pack_token_issue_sig ("ub_sig", - &ut->ub_sig)); - if (0 != - json_array_append_new (j_tokens, - j_token)) - { - GNUNET_break (0); - json_decref (j_coins); - json_decref (j_tokens); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - } - } - - pay_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("coins", - j_coins), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_steal ("tokens", - j_tokens)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("wallet_data", - poph->wallet_data)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("session_id", - poph->session_id))); - } - - eh = TALER_MERCHANT_curl_easy_get_ (poph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&poph->post_ctx, - eh, - pay_obj)) ) - { - GNUNET_break (0); - json_decref (pay_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (pay_obj); - poph->job = GNUNET_CURL_job_add2 (poph->ctx, - eh, - poph->post_ctx.headers, - &handle_pay_finished, - poph); - if (NULL == poph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_orders_pay_cancel ( - struct TALER_MERCHANT_PostOrdersPayHandle *poph) -{ - if (NULL != poph->job) - { - GNUNET_CURL_job_cancel (poph->job); - poph->job = NULL; - } - TALER_curl_easy_post_finished (&poph->post_ctx); - if (NULL != poph->paid_coins) - { - for (unsigned int i = 0; i < poph->num_paid_coins; i++) - { - TALER_denom_pub_free (&poph->paid_coins[i].denom_pub); - TALER_denom_sig_free (&poph->paid_coins[i].denom_sig); - GNUNET_free (poph->paid_coins[i].exchange_url); - } - GNUNET_free (poph->paid_coins); - } - if (NULL != poph->coins) - { - for (unsigned int i = 0; i < poph->num_coins; i++) - { - TALER_denom_pub_free (&poph->coins[i].denom_pub); - TALER_denom_sig_free (&poph->coins[i].denom_sig); - GNUNET_free (poph->coins[i].exchange_url); - } - GNUNET_free (poph->coins); - } - for (size_t j = 0; j<poph->num_donau_bkps; j++) - { - struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bpk - = &poph->donau_bkps[j]; - - GNUNET_CRYPTO_blinded_message_decref (bpk->blinded_udi.blinded_message); - } - GNUNET_free (poph->donau_bkps); - GNUNET_free (poph->donau_url); - GNUNET_free (poph->used_tokens); - GNUNET_free (poph->use_tokens); - GNUNET_free (poph->output_tokens); - json_decref (poph->output_tokens_json); - json_decref (poph->wallet_data); - GNUNET_free (poph->session_id); - GNUNET_free (poph->order_id); - GNUNET_free (poph->url); - GNUNET_free (poph->base_url); - GNUNET_free (poph); -} - - -/* end of merchant_api_post-orders-ORDER_ID-pay-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-pay.c b/src/lib/merchant_api_post-orders-ORDER_ID-pay.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,38 +17,40 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-orders-ORDER_ID-pay.c - * @brief Implementation of the POST /order/$ID/pay request - * of the merchant's HTTP API + * @file merchant_api_post-orders-ORDER_ID-pay-new.c + * @brief Implementation of the POST /orders/$ORDER_ID/pay request * @author Christian Grothoff * @author Marcello Stanisci */ #include "taler/platform.h" #include <curl/curl.h> -#include <gnunet/gnunet_common.h> -#include <gnunet/gnunet_json_lib.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <taler/taler-merchant/post-orders-ORDER_ID-pay.h> #include "merchant_api_curl_defaults.h" -#include <stdio.h> +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> -#include <taler/taler_exchange_service.h> #include <taler/taler_curl_lib.h> - +#include <taler/taler_signatures.h> +#if HAVE_DONAU_DONAU_SERVICE_H +#include <donau/donau_service.h> +#include <donau/donau_json_lib.h> +#endif /** - * @brief A Pay Handle + * Handle for a POST /orders/$ORDER_ID/pay operation. */ -struct TALER_MERCHANT_OrderPayHandle +struct TALER_MERCHANT_PostOrdersPayHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -58,14 +60,14 @@ struct TALER_MERCHANT_OrderPayHandle struct GNUNET_CURL_Job *job; /** - * Function to call with the result in "pay" @e mode. + * Function to call with the result. */ - TALER_MERCHANT_OrderPayCallback pay_cb; + TALER_MERCHANT_PostOrdersPayCallback cb; /** - * Closure for @a pay_cb. + * Closure for @a cb. */ - void *pay_cb_cls; + TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -78,72 +80,172 @@ struct TALER_MERCHANT_OrderPayHandle struct TALER_CURL_PostContext post_ctx; /** - * The coins we are paying with. + * Order identifier. + */ + char *order_id; + + /** + * The coins we are paying with (frontend mode, already signed). + */ + struct TALER_MERCHANT_PostOrdersPayPaidCoin *paid_coins; + + /** + * Number of @e paid_coins. */ - struct TALER_MERCHANT_PaidCoin *coins; + unsigned int num_paid_coins; /** - * Hash of the contract we are paying, set - * if @e am_wallet is true. + * Hash of the contract terms (wallet mode). */ struct TALER_PrivateContractHashP h_contract_terms; /** - * Public key of the merchant (instance) being paid, set - * if @e am_wallet is true. + * Public key of the merchant (wallet mode). */ struct TALER_MerchantPublicKeyP merchant_pub; /** - * JSON with the full reply, used during async - * processing. + * Merchant signature (wallet mode). + */ + struct TALER_MerchantSignatureP merchant_sig; + + /** + * Total payment amount (wallet mode). + */ + struct TALER_Amount amount; + + /** + * Maximum fee (wallet mode). + */ + struct TALER_Amount max_fee; + + /** + * Contract timestamp (wallet mode). + */ + struct GNUNET_TIME_Timestamp timestamp; + + /** + * Refund deadline (wallet mode). + */ + struct GNUNET_TIME_Timestamp refund_deadline; + + /** + * Payment deadline (wallet mode). + */ + struct GNUNET_TIME_Timestamp pay_deadline; + + /** + * Hash of merchant wire details (wallet mode). */ - json_t *full_reply; + struct TALER_MerchantWireHashP h_wire; /** - * Pointer into @e coins array for the coin that - * created a conflict (that we are checking). + * Choice index (wallet mode). */ - const struct TALER_MERCHANT_PaidCoin *error_pc; + int choice_index; /** - * Coin history that proves a conflict. + * Coins with private keys (wallet mode). */ - json_t *error_history; + struct TALER_MERCHANT_PostOrdersPayCoin *coins; /** - * Number of @e coins we are paying with. + * Number of @e coins (wallet mode). */ unsigned int num_coins; /** - * Set to true if this is the wallet API and we have - * initialized @e h_contract_terms and @e merchant_pub. + * Optional session identifier. */ - bool am_wallet; + char *session_id; + + /** + * Optional wallet data (JSON). + */ + json_t *wallet_data; + + /** + * Used tokens (public form, frontend mode). + */ + struct TALER_MERCHANT_PostOrdersPayUsedToken *used_tokens; + + /** + * Number of @e used_tokens. + */ + unsigned int num_used_tokens; + + /** + * Use tokens (private form, wallet mode). + */ + struct TALER_MERCHANT_PostOrdersPayUseToken *use_tokens; + + /** + * Number of @e use_tokens. + */ + unsigned int num_use_tokens; + + /** + * Output tokens (wallet mode). + */ + struct TALER_MERCHANT_PostOrdersPayOutputToken *output_tokens; + + /** + * Number of @e output_tokens. + */ + unsigned int num_output_tokens; + + /** + * Output tokens as JSON array (frontend mode). + */ + json_t *output_tokens_json; + + /** + * Base URL of the selected donau for donation receipts. + */ + char *donau_url; + + /** + * Tax year used for the donau. + */ + unsigned int donau_year; + /** + * Array of blinded donation receipts. + */ + struct DONAU_BlindedUniqueDonorIdentifierKeyPair *donau_bkps; + + /** + * Length of the @e donau_bkps array. + */ + size_t num_donau_bkps; + + /** + * Set to true if this is the wallet mode (private keys available). + */ + bool am_wallet; }; /** - * Parse blindly signed output tokens from response. + * Parse blindly signed output tokens from JSON response. * - * @param token_sigs the JSON array with the token signatures. Can be NULL. - * @param tokens where to store the parsed tokens. - * @param num_tokens where to store the length of the @a tokens array. + * @param token_sigs the JSON array with the token signatures, can be NULL + * @param[out] tokens where to store the parsed tokens + * @param[out] num_tokens where to store the length of the @a tokens array + * @return #GNUNET_YES on success */ static enum GNUNET_GenericReturnValue parse_tokens (const json_t *token_sigs, - struct TALER_MERCHANT_OutputToken **tokens, + struct TALER_MERCHANT_PostOrdersPayOutputToken **tokens, unsigned int *num_tokens) { GNUNET_array_grow (*tokens, *num_tokens, json_array_size (token_sigs)); - for (unsigned int i = 0; i<(*num_tokens); i++) + for (unsigned int i = 0; i < (*num_tokens); i++) { - struct TALER_MERCHANT_OutputToken *token = &(*tokens)[i]; + struct TALER_MERCHANT_PostOrdersPayOutputToken *token = &(*tokens)[i]; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_blinded_token_issue_sig ("blind_sig", &token->blinded_sig), @@ -174,9 +276,9 @@ parse_tokens (const json_t *token_sigs, /** * Function called when we're done processing the - * HTTP /pay request. + * HTTP POST /orders/$ORDER_ID/pay request. * - * @param cls the `struct TALER_MERCHANT_Pay` + * @param cls the `struct TALER_MERCHANT_PostOrdersPayHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -185,24 +287,16 @@ handle_pay_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrderPayHandle *oph = cls; + struct TALER_MERCHANT_PostOrdersPayHandle *poph = cls; const json_t *json = response; - struct TALER_MERCHANT_PayResponse pr = { + struct TALER_MERCHANT_PostOrdersPayResponse pr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received /pay response with status code %u\n", - (unsigned int) response_code); - - json_dumpf (json, - stderr, - JSON_INDENT (2)); - - oph->job = NULL; + poph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "/pay completed with response code %u\n", + "POST /orders/$ID/pay completed with response code %u\n", (unsigned int) response_code); switch (response_code) { @@ -210,7 +304,7 @@ handle_pay_finished (void *cls, pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: - if (oph->am_wallet) + if (poph->am_wallet) { const json_t *token_sigs = NULL; struct GNUNET_JSON_Specification spec[] = { @@ -252,8 +346,8 @@ handle_pay_finished (void *cls, } if (GNUNET_OK != - TALER_merchant_pay_verify (&oph->h_contract_terms, - &oph->merchant_pub, + TALER_merchant_pay_verify (&poph->h_contract_terms, + &poph->merchant_pub, &pr.details.ok.merchant_sig)) { GNUNET_break_op (0); @@ -263,9 +357,6 @@ handle_pay_finished (void *cls, } } break; - /* Tolerating Not Acceptable because sometimes - * - especially in tests - we might want to POST - * coins one at a time. */ case MHD_HTTP_NOT_ACCEPTABLE: pr.hr.ec = TALER_JSON_get_error_code (json); pr.hr.hint = TALER_JSON_get_error_hint (json); @@ -273,12 +364,8 @@ handle_pay_finished (void *cls, case MHD_HTTP_BAD_REQUEST: pr.hr.ec = TALER_JSON_get_error_code (json); pr.hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ break; case MHD_HTTP_PAYMENT_REQUIRED: - /* was originally paid, but then refunded */ pr.hr.ec = TALER_JSON_get_error_code (json); pr.hr.hint = TALER_JSON_get_error_hint (json); break; @@ -289,16 +376,10 @@ handle_pay_finished (void *cls, case MHD_HTTP_NOT_FOUND: pr.hr.ec = TALER_JSON_get_error_code (json); pr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ break; case MHD_HTTP_REQUEST_TIMEOUT: pr.hr.ec = TALER_JSON_get_error_code (json); pr.hr.hint = TALER_JSON_get_error_hint (json); - /* The merchant couldn't generate a timely response, likely because - it itself waited too long on the exchange. - Pass on to application. */ break; case MHD_HTTP_CONFLICT: TALER_MERCHANT_parse_error_details_ (json, @@ -309,18 +390,11 @@ handle_pay_finished (void *cls, TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); - /* The merchant says we are too late, the offer has expired or some - denomination key of a coin involved has expired. - Might be a disagreement in timestamps? Still, pass on to application. */ break; case MHD_HTTP_PRECONDITION_FAILED: TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); - /* Nothing really to verify, the merchant is blaming us for failing to - satisfy some constraint (likely it does not like our exchange because - of some disagreement on the PKI). We should pass the JSON reply to the - application */ break; case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: { @@ -331,7 +405,8 @@ handle_pay_finished (void *cls, GNUNET_break_op (0); pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; pr.hr.http_status = 0; - pr.hr.hint = "failed to parse exchange_base_urls field in response"; + pr.hr.hint + = "failed to parse exchange_base_urls field in response"; break; } { @@ -350,7 +425,8 @@ handle_pay_finished (void *cls, GNUNET_break_op (0); pr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; pr.hr.http_status = 0; - pr.hr.hint = "non-string value in exchange_base_urls in response"; + pr.hr.hint + = "non-string value in exchange_base_urls in response"; ok = false; break; } @@ -361,9 +437,9 @@ handle_pay_finished (void *cls, = (unsigned int) alen; pr.details.unavailable_for_legal_reasons.exchanges = ebua; - oph->pay_cb (oph->pay_cb_cls, - &pr); - TALER_MERCHANT_order_pay_cancel (oph); + poph->cb (poph->cb_cls, + &pr); + TALER_MERCHANT_post_orders_pay_cancel (poph); return; } } @@ -372,12 +448,8 @@ handle_pay_finished (void *cls, TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ break; case MHD_HTTP_BAD_GATEWAY: - /* Nothing really to verify, the merchant is blaming the exchange. - We should pass the JSON reply to the application */ TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); @@ -386,21 +458,16 @@ handle_pay_finished (void *cls, TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); - /* Exchange couldn't respond properly; the retry is - left to the application */ break; case MHD_HTTP_GATEWAY_TIMEOUT: TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); - /* Exchange couldn't respond in a timely fashion; - the retry is left to the application */ break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, &pr.hr); - /* unexpected response code */ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, @@ -408,208 +475,53 @@ handle_pay_finished (void *cls, GNUNET_break_op (0); break; } - oph->pay_cb (oph->pay_cb_cls, - &pr); - TALER_MERCHANT_order_pay_cancel (oph); + poph->cb (poph->cb_cls, + &pr); + TALER_MERCHANT_post_orders_pay_cancel (poph); } -struct TALER_MERCHANT_OrderPayHandle * -TALER_MERCHANT_order_pay_frontend ( +struct TALER_MERCHANT_PostOrdersPayHandle * +TALER_MERCHANT_post_orders_pay_frontend_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, + const char *url, const char *order_id, - const char *session_id, - const json_t *wallet_data, unsigned int num_coins, - const struct TALER_MERCHANT_PaidCoin coins[static num_coins], - unsigned int num_tokens, - const struct TALER_MERCHANT_UsedToken *tokens, - json_t *j_output_tokens, // FIXME: not used, remove? - TALER_MERCHANT_OrderPayCallback pay_cb, - void *pay_cb_cls) + const struct TALER_MERCHANT_PostOrdersPayPaidCoin coins[static num_coins]) { - struct TALER_MERCHANT_OrderPayHandle *oph; - json_t *pay_obj; - json_t *j_coins; - json_t *j_tokens = NULL; - CURL *eh; - struct TALER_Amount total_fee; - struct TALER_Amount total_amount; + struct TALER_MERCHANT_PostOrdersPayHandle *poph; - j_coins = json_array (); - GNUNET_assert (NULL != j_coins); - for (unsigned int i = 0; i<num_coins; i++) + poph = GNUNET_new (struct TALER_MERCHANT_PostOrdersPayHandle); + poph->ctx = ctx; + poph->base_url = GNUNET_strdup (url); + poph->order_id = GNUNET_strdup (order_id); + poph->am_wallet = false; + poph->num_paid_coins = num_coins; + poph->paid_coins = GNUNET_new_array ( + num_coins, + struct TALER_MERCHANT_PostOrdersPayPaidCoin); + for (unsigned int i = 0; i < num_coins; i++) { - json_t *j_coin; - const struct TALER_MERCHANT_PaidCoin *pc = &coins[i]; - struct TALER_Amount fee; - struct TALER_DenominationHashP denom_hash; - - if (0 > - TALER_amount_subtract (&fee, - &pc->amount_with_fee, - &pc->amount_without_fee)) - { - /* Integer underflow, fee larger than total amount? - This should not happen (client violated API!) */ - GNUNET_break (0); - json_decref (j_coins); - return NULL; - } - if (0 == i) - { - total_fee = fee; - total_amount = pc->amount_with_fee; - } - else - { - if ( (0 > - TALER_amount_add (&total_fee, - &total_fee, - &fee)) || - (0 > - TALER_amount_add (&total_amount, - &total_amount, - &pc->amount_with_fee)) ) - { - /* integer overflow */ - GNUNET_break (0); - json_decref (j_coins); - return NULL; - } - } + struct TALER_MERCHANT_PostOrdersPayPaidCoin *dst = &poph->paid_coins[i]; + const struct TALER_MERCHANT_PostOrdersPayPaidCoin *src = &coins[i]; - TALER_denom_pub_hash (&pc->denom_pub, - &denom_hash); - /* create JSON for this coin */ - j_coin = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("contribution", - &pc->amount_with_fee), - GNUNET_JSON_pack_data_auto ("coin_pub", - &pc->coin_pub), - GNUNET_JSON_pack_string ("exchange_url", - pc->exchange_url), - GNUNET_JSON_pack_data_auto ("h_denom", - &denom_hash), - TALER_JSON_pack_denom_sig ("ub_sig", - &pc->denom_sig), - GNUNET_JSON_pack_data_auto ("coin_sig", - &pc->coin_sig)); - if (0 != - json_array_append_new (j_coins, - j_coin)) - { - GNUNET_break (0); - json_decref (j_coins); - return NULL; - } + *dst = *src; + /* deep copy fields that need it */ + TALER_denom_pub_copy (&dst->denom_pub, + &src->denom_pub); + TALER_denom_sig_copy (&dst->denom_sig, + &src->denom_sig); + dst->exchange_url = GNUNET_strdup (src->exchange_url); } - - if (0 < num_tokens) - { - j_tokens = json_array (); - GNUNET_assert (NULL != j_tokens); - for (unsigned int i = 0; i<num_tokens; i++) - { - json_t *j_token; - const struct TALER_MERCHANT_UsedToken *ut = &tokens[i]; - - j_token = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("token_sig", - &ut->token_sig), - GNUNET_JSON_pack_data_auto ("token_pub", - &ut->token_pub), - GNUNET_JSON_pack_data_auto ("h_issue", - &ut->issue_pub.public_key->pub_key_hash), - TALER_JSON_pack_token_issue_sig ("ub_sig", - &ut->ub_sig)); - if (0 != - json_array_append_new (j_tokens, - j_token)) - { - GNUNET_break (0); - json_decref (j_tokens); - return NULL; - } - } - } - - pay_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_array_steal ("coins", - j_coins), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_steal ("tokens", - j_tokens)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("wallet_data", - (json_t *) wallet_data)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("session_id", - session_id))); - - json_dumpf (pay_obj, - stderr, - JSON_INDENT (2)); - - oph = GNUNET_new (struct TALER_MERCHANT_OrderPayHandle); - oph->ctx = ctx; - oph->pay_cb = pay_cb; - oph->pay_cb_cls = pay_cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/pay", - order_id); - oph->url = TALER_url_join (merchant_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == oph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (pay_obj); - GNUNET_free (oph); - return NULL; - } - oph->num_coins = num_coins; - oph->coins = GNUNET_new_array (num_coins, - struct TALER_MERCHANT_PaidCoin); - GNUNET_memcpy (oph->coins, - coins, - num_coins * sizeof (struct TALER_MERCHANT_PaidCoin)); - - eh = TALER_MERCHANT_curl_easy_get_ (oph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&oph->post_ctx, - eh, - pay_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (pay_obj); - GNUNET_free (oph->url); - GNUNET_free (oph); - return NULL; - } - json_decref (pay_obj); - oph->job = GNUNET_CURL_job_add2 (ctx, - eh, - oph->post_ctx.headers, - &handle_pay_finished, - oph); - return oph; + return poph; } -struct TALER_MERCHANT_OrderPayHandle * -TALER_MERCHANT_order_pay ( +struct TALER_MERCHANT_PostOrdersPayHandle * +TALER_MERCHANT_post_orders_pay_create ( struct GNUNET_CURL_Context *ctx, - const char *merchant_url, - const char *session_id, + const char *url, + const char *order_id, const struct TALER_PrivateContractHashP *h_contract_terms, int choice_index, const struct TALER_Amount *amount, @@ -620,19 +532,10 @@ TALER_MERCHANT_order_pay ( struct GNUNET_TIME_Timestamp refund_deadline, struct GNUNET_TIME_Timestamp pay_deadline, const struct TALER_MerchantWireHashP *h_wire, - const char *order_id, unsigned int num_coins, - const struct TALER_MERCHANT_PayCoin coins[static num_coins], - unsigned int num_tokens, - const struct TALER_MERCHANT_UseToken *tokens, - unsigned int num_output_tokens, - const struct TALER_MERCHANT_OutputToken *output_tokens, - TALER_MERCHANT_OrderPayCallback pay_cb, - void *pay_cb_cls) + const struct TALER_MERCHANT_PostOrdersPayCoin coins[static num_coins]) { - json_t *j_output_tokens = NULL; - const json_t *wallet_data = NULL; - struct GNUNET_HashCode wallet_data_hash; + struct TALER_MERCHANT_PostOrdersPayHandle *poph; if (GNUNET_YES != TALER_amount_cmp_currency (amount, @@ -641,150 +544,580 @@ TALER_MERCHANT_order_pay ( GNUNET_break (0); return NULL; } - if ((0 < num_tokens || 0 < num_output_tokens) && 0 > choice_index) + + poph = GNUNET_new (struct TALER_MERCHANT_PostOrdersPayHandle); + poph->ctx = ctx; + poph->base_url = GNUNET_strdup (url); + poph->order_id = GNUNET_strdup (order_id); + poph->am_wallet = true; + poph->h_contract_terms = *h_contract_terms; + poph->choice_index = choice_index; + poph->amount = *amount; + poph->max_fee = *max_fee; + poph->merchant_pub = *merchant_pub; + poph->merchant_sig = *merchant_sig; + poph->timestamp = timestamp; + poph->refund_deadline = refund_deadline; + poph->pay_deadline = pay_deadline; + poph->h_wire = *h_wire; + poph->num_coins = num_coins; + poph->coins = GNUNET_new_array (num_coins, + struct TALER_MERCHANT_PostOrdersPayCoin); + for (unsigned int i = 0; i < num_coins; i++) { - /* Tokens (input or output) require a valid choice_index to be set. - Only contracts with coices can use or issue tokens. */ - GNUNET_break (0); - return NULL; + struct TALER_MERCHANT_PostOrdersPayCoin *dst = &poph->coins[i]; + const struct TALER_MERCHANT_PostOrdersPayCoin *src = &coins[i]; + + *dst = *src; + TALER_denom_pub_copy (&dst->denom_pub, + &src->denom_pub); + TALER_denom_sig_copy (&dst->denom_sig, + &src->denom_sig); + dst->exchange_url = GNUNET_strdup (src->exchange_url); } - if (0 < num_output_tokens) - { - /* Build token envelopes json array. */ - j_output_tokens = json_array (); - GNUNET_assert (NULL != j_output_tokens); - for (unsigned int i = 0; i<num_output_tokens; i++) - { - json_t *j_token_ev; - const struct TALER_MERCHANT_OutputToken *ev = &output_tokens[i]; + return poph; +} - j_token_ev = GNUNET_JSON_PACK ( - TALER_JSON_pack_token_envelope (NULL, - &ev->envelope)); - if (0 != - json_array_append_new (j_output_tokens, - j_token_ev)) +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_orders_pay_set_options_ ( + struct TALER_MERCHANT_PostOrdersPayHandle *poph, + unsigned int num_options, + const struct TALER_MERCHANT_PostOrdersPayOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_SESSION_ID: + GNUNET_free (poph->session_id); + if (NULL != options[i].details.session_id) + poph->session_id = GNUNET_strdup (options[i].details.session_id); + break; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_WALLET_DATA: + json_decref (poph->wallet_data); + poph->wallet_data = NULL; + if (NULL != options[i].details.wallet_data) + poph->wallet_data = json_incref ( + (json_t *) options[i].details.wallet_data); + break; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USED_TOKENS: + GNUNET_free (poph->used_tokens); + poph->num_used_tokens = options[i].details.used_tokens.num; + if (0 < poph->num_used_tokens) { - GNUNET_break (0); - json_decref (j_output_tokens); - return NULL; + poph->used_tokens = GNUNET_new_array ( + poph->num_used_tokens, + struct TALER_MERCHANT_PostOrdersPayUsedToken); + GNUNET_memcpy (poph->used_tokens, + options[i].details.used_tokens.tokens, + poph->num_used_tokens + * sizeof (struct TALER_MERCHANT_PostOrdersPayUsedToken)); + } + break; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_USE_TOKENS: + GNUNET_free (poph->use_tokens); + poph->num_use_tokens = options[i].details.use_tokens.num; + if (0 < poph->num_use_tokens) + { + poph->use_tokens = GNUNET_new_array ( + poph->num_use_tokens, + struct TALER_MERCHANT_PostOrdersPayUseToken); + GNUNET_memcpy (poph->use_tokens, + options[i].details.use_tokens.tokens, + poph->num_use_tokens + * sizeof (struct TALER_MERCHANT_PostOrdersPayUseToken)); } + break; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS: + GNUNET_free (poph->output_tokens); + poph->num_output_tokens = options[i].details.output_tokens.num; + if (0 < poph->num_output_tokens) + { + poph->output_tokens = GNUNET_new_array ( + poph->num_output_tokens, + struct TALER_MERCHANT_PostOrdersPayOutputToken); + GNUNET_memcpy ( + poph->output_tokens, + options[i].details.output_tokens.tokens, + poph->num_output_tokens + * sizeof (struct TALER_MERCHANT_PostOrdersPayOutputToken)); + } + break; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_TOKENS_JSON: + json_decref (poph->output_tokens_json); + poph->output_tokens_json = NULL; + if (NULL != options[i].details.output_tokens_json) + poph->output_tokens_json = json_incref ( + options[i].details.output_tokens_json); + break; + case TALER_MERCHANT_POST_ORDERS_PAY_OPTION_OUTPUT_DONAU: +#if HAVE_DONAU_DONAU_SERVICE_H + if (NULL != poph->donau_url) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Only one set of donation receipts is allowed to be specified\n"); + return GNUNET_NO; + } + poph->donau_url + = GNUNET_strdup (options[i].details.output_donau.donau_base_url); + poph->donau_year + = options[i].details.output_donau.year; + poph->num_donau_bkps = options[i].details.output_donau.num_bkps; + poph->donau_bkps = GNUNET_new_array ( + poph->num_donau_bkps, + struct DONAU_BlindedUniqueDonorIdentifierKeyPair); + for (size_t j=0; j<poph->num_donau_bkps; j++) + { + const struct DONAU_BlindedUniqueDonorIdentifierKeyPair *src + = &options[i].details.output_donau.bkps[j]; + struct DONAU_BlindedUniqueDonorIdentifierKeyPair *dst + = &poph->donau_bkps[j]; + + dst->h_donation_unit_pub = src->h_donation_unit_pub; + dst->blinded_udi.blinded_message + = GNUNET_CRYPTO_blinded_message_incref ( + src->blinded_udi.blinded_message); + } + break; +#else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Donation receipts are not supported by this build!\n"); + return GNUNET_NO; +#endif + default: + GNUNET_break (0); + return GNUNET_SYSERR; } } - if (0 <= choice_index) + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_pay_start ( + struct TALER_MERCHANT_PostOrdersPayHandle *poph, + TALER_MERCHANT_PostOrdersPayCallback cb, + TALER_MERCHANT_POST_ORDERS_PAY_RESULT_CLOSURE *cb_cls) +{ + json_t *pay_obj; + json_t *j_coins; + json_t *j_tokens = NULL; + json_t *j_output_tokens = NULL; + CURL *eh; + + poph->cb = cb; + poph->cb_cls = cb_cls; { - wallet_data = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_int64 ("choice_index", - choice_index), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_incref ("tokens_evs", - j_output_tokens))); - TALER_json_hash (wallet_data, - &wallet_data_hash); + char *path; + + GNUNET_asprintf (&path, + "orders/%s/pay", + poph->order_id); + poph->url = TALER_url_join (poph->base_url, + path, + NULL); + GNUNET_free (path); } + if (NULL == poph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + + if (poph->am_wallet) { - struct TALER_MERCHANT_PaidCoin pc[num_coins]; - struct TALER_MERCHANT_UsedToken ut[num_tokens]; + /* Wallet mode: sign coins and tokens, build wallet_data */ + json_t *wallet_data = poph->wallet_data; + json_t *j_donau_data = NULL; + struct GNUNET_HashCode wallet_data_hash; - for (unsigned int i = 0; i<num_coins; i++) + if (NULL != poph->donau_url) { - const struct TALER_MERCHANT_PayCoin *coin = &coins[i]; // coin priv. - struct TALER_MERCHANT_PaidCoin *p = &pc[i]; // coin pub. + json_t *budis; + + budis = json_array (); + GNUNET_assert (NULL != budis); + for (size_t i=0; i<poph->num_donau_bkps; i++) + { + const struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkp + = &poph->donau_bkps[i]; + json_t *budikeypair = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("h_donation_unit_pub", + &bkp->h_donation_unit_pub), + DONAU_JSON_pack_blinded_donation_identifier ("blinded_udi", + &bkp->blinded_udi)); + + GNUNET_assert (0 == + json_array_append_new (budis, + budikeypair)); + } + + j_donau_data = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("url", + poph->donau_url), + GNUNET_JSON_pack_int64 ("year", + poph->donau_year), + GNUNET_JSON_pack_array_steal ("budikeypairs", + budis)); + } + + /* Build output token envelopes JSON if we have output tokens */ + if (0 < poph->num_output_tokens) + { + j_output_tokens = json_array (); + GNUNET_assert (NULL != j_output_tokens); + for (unsigned int i = 0; i < poph->num_output_tokens; i++) + { + json_t *j_token_ev; + const struct TALER_MERCHANT_PostOrdersPayOutputToken *ev + = &poph->output_tokens[i]; + + j_token_ev = GNUNET_JSON_PACK ( + TALER_JSON_pack_token_envelope (NULL, + &ev->envelope)); + if (0 != + json_array_append_new (j_output_tokens, + j_token_ev)) + { + GNUNET_break (0); + json_decref (j_output_tokens); + json_decref (j_donau_data); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } + } + } + else if (NULL != poph->output_tokens_json) + { + j_output_tokens = json_incref (poph->output_tokens_json); + } + + /* Build wallet_data if choice_index is valid */ + if (0 <= poph->choice_index) + { + if (NULL == wallet_data) + { + wallet_data = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_int64 ("choice_index", + poph->choice_index), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("donau", + j_donau_data)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_array_incref ("tokens_evs", + j_output_tokens))); + } + TALER_json_hash (wallet_data, + &wallet_data_hash); + } + json_decref (j_donau_data); + j_donau_data = NULL; + + if ( (0 < poph->num_use_tokens || 0 < poph->num_output_tokens + || NULL != poph->output_tokens_json) + && (0 > poph->choice_index) ) + { + GNUNET_break (0); + json_decref (j_output_tokens); + if ( (NULL == poph->wallet_data) && + (NULL != wallet_data) ) + json_decref (wallet_data); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } + + /* Sign coins */ + j_coins = json_array (); + GNUNET_assert (NULL != j_coins); + for (unsigned int i = 0; i < poph->num_coins; i++) + { + const struct TALER_MERCHANT_PostOrdersPayCoin *coin = &poph->coins[i]; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; struct TALER_Amount fee; struct TALER_DenominationHashP h_denom_pub; + json_t *j_coin; if (0 > TALER_amount_subtract (&fee, &coin->amount_with_fee, &coin->amount_without_fee)) { - /* Integer underflow, fee larger than total amount? - This should not happen (client violated API!) */ GNUNET_break (0); - return NULL; + json_decref (j_coins); + json_decref (j_output_tokens); + if ( (NULL == poph->wallet_data) && + (NULL != wallet_data) ) + json_decref (wallet_data); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } TALER_denom_pub_hash (&coin->denom_pub, &h_denom_pub); TALER_wallet_deposit_sign (&coin->amount_with_fee, &fee, - h_wire, - h_contract_terms, - (NULL != wallet_data) + &poph->h_wire, + &poph->h_contract_terms, + (0 <= poph->choice_index) ? &wallet_data_hash : NULL, - coin->h_age_commitment, - NULL /* h_extensions! */, + GNUNET_is_zero (&coin->h_age_commitment) + ? NULL + : &coin->h_age_commitment, + NULL /* h_extensions */, &h_denom_pub, - timestamp, - merchant_pub, - refund_deadline, + poph->timestamp, + &poph->merchant_pub, + poph->refund_deadline, &coin->coin_priv, - &p->coin_sig); - p->denom_pub = coin->denom_pub; - p->denom_sig = coin->denom_sig; - p->denom_value = coin->denom_value; + &coin_sig); GNUNET_CRYPTO_eddsa_key_get_public (&coin->coin_priv.eddsa_priv, - &p->coin_pub.eddsa_pub); - p->amount_with_fee = coin->amount_with_fee; - p->amount_without_fee = coin->amount_without_fee; - p->exchange_url = coin->exchange_url; + &coin_pub.eddsa_pub); + j_coin = GNUNET_JSON_PACK ( + TALER_JSON_pack_amount ("contribution", + &coin->amount_with_fee), + GNUNET_JSON_pack_data_auto ("coin_pub", + &coin_pub), + GNUNET_JSON_pack_string ("exchange_url", + coin->exchange_url), + GNUNET_JSON_pack_data_auto ("h_denom", + &h_denom_pub), + TALER_JSON_pack_denom_sig ("ub_sig", + &coin->denom_sig), + GNUNET_JSON_pack_data_auto ("coin_sig", + &coin_sig)); + if (0 != + json_array_append_new (j_coins, + j_coin)) + { + GNUNET_break (0); + json_decref (j_coins); + json_decref (j_output_tokens); + if ( (NULL == poph->wallet_data) && + (NULL != wallet_data) ) + json_decref (wallet_data); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } } - for (unsigned int i = 0; i<num_tokens; i++) + + /* Sign use tokens */ + if (0 < poph->num_use_tokens) { - const struct TALER_MERCHANT_UseToken *token = &tokens[i]; - struct TALER_MERCHANT_UsedToken *t = &ut[i]; - - TALER_wallet_token_use_sign (h_contract_terms, - &wallet_data_hash, // checked for != NULL above - &token->token_priv, - &t->token_sig); - t->ub_sig = token->ub_sig; - t->issue_pub = token->issue_pub; - GNUNET_CRYPTO_eddsa_key_get_public (&token->token_priv.private_key, - &t->token_pub.public_key); + j_tokens = json_array (); + GNUNET_assert (NULL != j_tokens); + for (unsigned int i = 0; i < poph->num_use_tokens; i++) + { + const struct TALER_MERCHANT_PostOrdersPayUseToken *token + = &poph->use_tokens[i]; + struct TALER_TokenUseSignatureP token_sig; + struct TALER_TokenUsePublicKeyP token_pub; + json_t *j_token; + + TALER_wallet_token_use_sign (&poph->h_contract_terms, + &wallet_data_hash, + &token->token_priv, + &token_sig); + GNUNET_CRYPTO_eddsa_key_get_public ( + &token->token_priv.private_key, + &token_pub.public_key); + j_token = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("token_sig", + &token_sig), + GNUNET_JSON_pack_data_auto ("token_pub", + &token_pub), + GNUNET_JSON_pack_data_auto ( + "h_issue", + &token->issue_pub.public_key->pub_key_hash), + TALER_JSON_pack_token_issue_sig ("ub_sig", + &token->ub_sig)); + if (0 != + json_array_append_new (j_tokens, + j_token)) + { + GNUNET_break (0); + json_decref (j_coins); + json_decref (j_tokens); + json_decref (j_output_tokens); + if ( (NULL == poph->wallet_data) && + (NULL != wallet_data) ) + json_decref (wallet_data); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } + } } + + pay_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("coins", + j_coins), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_array_steal ("tokens", + j_tokens)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("wallet_data", + wallet_data)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("session_id", + poph->session_id))); + if ( (NULL == poph->wallet_data) && + (NULL != wallet_data) ) + json_decref (wallet_data); + } + else + { + /* Frontend mode: coins are already signed */ + j_coins = json_array (); + GNUNET_assert (NULL != j_coins); + for (unsigned int i = 0; i < poph->num_paid_coins; i++) { - struct TALER_MERCHANT_OrderPayHandle *oph; - - oph = TALER_MERCHANT_order_pay_frontend (ctx, - merchant_url, - order_id, - session_id, - wallet_data, - num_coins, - pc, - num_tokens, - ut, - j_output_tokens, - pay_cb, - pay_cb_cls); - if (NULL == oph) - return NULL; - oph->h_contract_terms = *h_contract_terms; - oph->merchant_pub = *merchant_pub; - oph->am_wallet = true; - return oph; + const struct TALER_MERCHANT_PostOrdersPayPaidCoin *pc + = &poph->paid_coins[i]; + struct TALER_DenominationHashP denom_hash; + json_t *j_coin; + + TALER_denom_pub_hash (&pc->denom_pub, + &denom_hash); + j_coin = GNUNET_JSON_PACK ( + TALER_JSON_pack_amount ("contribution", + &pc->amount_with_fee), + GNUNET_JSON_pack_data_auto ("coin_pub", + &pc->coin_pub), + GNUNET_JSON_pack_string ("exchange_url", + pc->exchange_url), + GNUNET_JSON_pack_data_auto ("h_denom", + &denom_hash), + TALER_JSON_pack_denom_sig ("ub_sig", + &pc->denom_sig), + GNUNET_JSON_pack_data_auto ("coin_sig", + &pc->coin_sig)); + if (0 != + json_array_append_new (j_coins, + j_coin)) + { + GNUNET_break (0); + json_decref (j_coins); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } } + + /* Build used tokens JSON (frontend mode) */ + if (0 < poph->num_used_tokens) + { + j_tokens = json_array (); + GNUNET_assert (NULL != j_tokens); + for (unsigned int i = 0; i < poph->num_used_tokens; i++) + { + const struct TALER_MERCHANT_PostOrdersPayUsedToken *ut + = &poph->used_tokens[i]; + json_t *j_token; + + j_token = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("token_sig", + &ut->token_sig), + GNUNET_JSON_pack_data_auto ("token_pub", + &ut->token_pub), + GNUNET_JSON_pack_data_auto ( + "h_issue", + &ut->issue_pub.public_key->pub_key_hash), + TALER_JSON_pack_token_issue_sig ("ub_sig", + &ut->ub_sig)); + if (0 != + json_array_append_new (j_tokens, + j_token)) + { + GNUNET_break (0); + json_decref (j_coins); + json_decref (j_tokens); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } + } + } + + pay_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("coins", + j_coins), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_array_steal ("tokens", + j_tokens)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("wallet_data", + poph->wallet_data)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("session_id", + poph->session_id))); + } + + eh = TALER_MERCHANT_curl_easy_get_ (poph->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&poph->post_ctx, + eh, + pay_obj)) ) + { + GNUNET_break (0); + json_decref (pay_obj); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } + json_decref (pay_obj); + poph->job = GNUNET_CURL_job_add2 (poph->ctx, + eh, + poph->post_ctx.headers, + &handle_pay_finished, + poph); + if (NULL == poph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_order_pay_cancel (struct TALER_MERCHANT_OrderPayHandle *oph) +TALER_MERCHANT_post_orders_pay_cancel ( + struct TALER_MERCHANT_PostOrdersPayHandle *poph) { - if (NULL != oph->job) + if (NULL != poph->job) { - GNUNET_CURL_job_cancel (oph->job); - oph->job = NULL; + GNUNET_CURL_job_cancel (poph->job); + poph->job = NULL; + } + TALER_curl_easy_post_finished (&poph->post_ctx); + if (NULL != poph->paid_coins) + { + for (unsigned int i = 0; i < poph->num_paid_coins; i++) + { + TALER_denom_pub_free (&poph->paid_coins[i].denom_pub); + TALER_denom_sig_free (&poph->paid_coins[i].denom_sig); + GNUNET_free (poph->paid_coins[i].exchange_url); + } + GNUNET_free (poph->paid_coins); + } + if (NULL != poph->coins) + { + for (unsigned int i = 0; i < poph->num_coins; i++) + { + TALER_denom_pub_free (&poph->coins[i].denom_pub); + TALER_denom_sig_free (&poph->coins[i].denom_sig); + GNUNET_free (poph->coins[i].exchange_url); + } + GNUNET_free (poph->coins); + } + for (size_t j = 0; j<poph->num_donau_bkps; j++) + { + struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bpk + = &poph->donau_bkps[j]; + + GNUNET_CRYPTO_blinded_message_decref (bpk->blinded_udi.blinded_message); } - TALER_curl_easy_post_finished (&oph->post_ctx); - json_decref (oph->error_history); - json_decref (oph->full_reply); - GNUNET_free (oph->coins); - GNUNET_free (oph->url); - GNUNET_free (oph); + GNUNET_free (poph->donau_bkps); + GNUNET_free (poph->donau_url); + GNUNET_free (poph->used_tokens); + GNUNET_free (poph->use_tokens); + GNUNET_free (poph->output_tokens); + json_decref (poph->output_tokens_json); + json_decref (poph->wallet_data); + GNUNET_free (poph->session_id); + GNUNET_free (poph->order_id); + GNUNET_free (poph->url); + GNUNET_free (poph->base_url); + GNUNET_free (poph); } -/* end of merchant_api_post_order_pay.c */ +/* end of merchant_api_post-orders-ORDER_ID-pay-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-refund-new.c b/src/lib/merchant_api_post-orders-ORDER_ID-refund-new.c @@ -1,370 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-orders-ORDER_ID-refund-new.c - * @brief Implementation of the POST /orders/$ORDER_ID/refund request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-refund-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> -#include <taler/taler_signatures.h> - - -/** - * Maximum number of refunds we return. - */ -#define MAX_REFUNDS 1024 - - -/** - * Handle for a POST /orders/$ORDER_ID/refund operation. - */ -struct TALER_MERCHANT_PostOrdersRefundHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostOrdersRefundCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order identifier. - */ - char *order_id; - - /** - * Hash of the contract terms. - */ - struct TALER_PrivateContractHashP h_contract_terms; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /orders/$ORDER_ID/refund request. - * - * @param cls the `struct TALER_MERCHANT_PostOrdersRefundHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_refund_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostOrdersRefundHandle *porh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostOrdersRefundResponse orr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - porh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /orders/$ID/refund completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - orr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - { - const json_t *refunds; - unsigned int refund_len; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_array_const ( - "refunds", - &refunds), - GNUNET_JSON_spec_fixed_auto ( - "merchant_pub", - &orr.details.ok.merchant_pub), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - orr.hr.http_status = 0; - break; - } - refund_len = (unsigned int) json_array_size (refunds); - if ( (json_array_size (refunds) != (size_t) refund_len) || - (refund_len > MAX_REFUNDS) ) - { - GNUNET_break (0); - orr.hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; - orr.hr.http_status = 0; - break; - } - { - struct TALER_MERCHANT_PostOrdersRefundDetail rds[GNUNET_NZL ( - refund_len)]; - - memset (rds, - 0, - sizeof (rds)); - for (unsigned int i = 0; i < refund_len; i++) - { - struct TALER_MERCHANT_PostOrdersRefundDetail *rd = &rds[i]; - const json_t *jrefund = json_array_get (refunds, - i); - const char *refund_status_type; - uint32_t exchange_status; - uint32_t eec = 0; - struct GNUNET_JSON_Specification espec[] = { - GNUNET_JSON_spec_string ("type", - &refund_status_type), - GNUNET_JSON_spec_uint32 ("exchange_status", - &exchange_status), - GNUNET_JSON_spec_uint64 ("rtransaction_id", - &rd->rtransaction_id), - GNUNET_JSON_spec_fixed_auto ("coin_pub", - &rd->coin_pub), - TALER_JSON_spec_amount_any ("refund_amount", - &rd->refund_amount), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_object_const ("exchange_reply", - &rd->exchange_reply), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ("exchange_code", - &eec), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (jrefund, - espec, - NULL, NULL)) - { - GNUNET_break_op (0); - orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - orr.hr.http_status = 0; - goto finish; - } - - rd->exchange_http_status = exchange_status; - rd->ec = (enum TALER_ErrorCode) eec; - switch (exchange_status) - { - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification rspec[] = { - GNUNET_JSON_spec_fixed_auto ("exchange_sig", - &rd->exchange_sig), - GNUNET_JSON_spec_fixed_auto ("exchange_pub", - &rd->exchange_pub), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (jrefund, - rspec, - NULL, - NULL)) - { - GNUNET_break_op (0); - orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - orr.hr.http_status = 0; - goto finish; - } - if (0 != strcmp ("success", - refund_status_type)) - { - GNUNET_break_op (0); - orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - orr.hr.http_status = 0; - goto finish; - } - } - break; - default: - if (0 != strcmp ("failure", - refund_status_type)) - { - GNUNET_break_op (0); - orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - orr.hr.http_status = 0; - goto finish; - } - } - } - - orr.details.ok.refunds = rds; - orr.details.ok.num_refunds = refund_len; - porh->cb (porh->cb_cls, - &orr); - TALER_MERCHANT_post_orders_refund_cancel (porh); - return; - } - } - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_CONFLICT: - case MHD_HTTP_NOT_FOUND: - orr.hr.ec = TALER_JSON_get_error_code (json); - orr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - GNUNET_break_op (0); - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &orr.hr); - break; - } -finish: - porh->cb (porh->cb_cls, - &orr); - TALER_MERCHANT_post_orders_refund_cancel (porh); -} - - -struct TALER_MERCHANT_PostOrdersRefundHandle * -TALER_MERCHANT_post_orders_refund_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_PrivateContractHashP *h_contract_terms) -{ - struct TALER_MERCHANT_PostOrdersRefundHandle *porh; - - porh = GNUNET_new (struct TALER_MERCHANT_PostOrdersRefundHandle); - porh->ctx = ctx; - porh->base_url = GNUNET_strdup (url); - porh->order_id = GNUNET_strdup (order_id); - porh->h_contract_terms = *h_contract_terms; - return porh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_orders_refund_start ( - struct TALER_MERCHANT_PostOrdersRefundHandle *porh, - TALER_MERCHANT_PostOrdersRefundCallback cb, - TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - porh->cb = cb; - porh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "orders/%s/refund", - porh->order_id); - porh->url = TALER_url_join (porh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == porh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("h_contract", - &porh->h_contract_terms)); - eh = TALER_MERCHANT_curl_easy_get_ (porh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&porh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - porh->job = GNUNET_CURL_job_add2 (porh->ctx, - eh, - porh->post_ctx.headers, - &handle_refund_finished, - porh); - if (NULL == porh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_orders_refund_cancel ( - struct TALER_MERCHANT_PostOrdersRefundHandle *porh) -{ - if (NULL != porh->job) - { - GNUNET_CURL_job_cancel (porh->job); - porh->job = NULL; - } - TALER_curl_easy_post_finished (&porh->post_ctx); - GNUNET_free (porh->order_id); - GNUNET_free (porh->url); - GNUNET_free (porh->base_url); - GNUNET_free (porh); -} - - -/* end of merchant_api_post-orders-ORDER_ID-refund-new.c */ diff --git a/src/lib/merchant_api_post-orders-ORDER_ID-refund.c b/src/lib/merchant_api_post-orders-ORDER_ID-refund.c @@ -1,23 +1,25 @@ /* This file is part of TALER - Copyright (C) 2020-2023 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1, + or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + TALER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> + You should have received a copy of the GNU Lesser General + Public License along with TALER; see the file COPYING.LGPL. + If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-orders-ORDER_ID-refund.c - * @brief Implementation of the (public) POST /orders/ID/refund request - * @author Jonathan Buchanan + * @file merchant_api_post-orders-ORDER_ID-refund-new.c + * @brief Implementation of the POST /orders/$ORDER_ID/refund request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,94 +27,112 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <taler/taler-merchant/post-orders-ORDER_ID-refund.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> +#include <taler/taler_signatures.h> + /** * Maximum number of refunds we return. */ #define MAX_REFUNDS 1024 + /** - * Handle for a (public) POST /orders/ID/refund operation. + * Handle for a POST /orders/$ORDER_ID/refund operation. */ -struct TALER_MERCHANT_WalletOrderRefundHandle +struct TALER_MERCHANT_PostOrdersRefundHandle { /** - * Complete URL where the backend offers /refund + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * Minor context that holds body and headers. + * Handle for the request. */ - struct TALER_CURL_PostContext post_ctx; + struct GNUNET_CURL_Job *job; + + /** + * Function to call with the result. + */ + TALER_MERCHANT_PostOrdersRefundCallback cb; /** - * The CURL context to connect to the backend + * Closure for @a cb. + */ + TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cb_cls; + + /** + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; /** - * The callback to pass the backend response to + * Minor context that holds body and headers. */ - TALER_MERCHANT_WalletRefundCallback cb; + struct TALER_CURL_PostContext post_ctx; /** - * Clasure to pass to the callback + * Order identifier. */ - void *cb_cls; + char *order_id; /** - * Handle for the request + * Hash of the contract terms. */ - struct GNUNET_CURL_Job *job; + struct TALER_PrivateContractHashP h_contract_terms; }; /** - * Callback to process (public) POST /orders/ID/refund response + * Function called when we're done processing the + * HTTP POST /orders/$ORDER_ID/refund request. * - * @param cls the `struct TALER_MERCHANT_OrderRefundHandle` + * @param cls the `struct TALER_MERCHANT_PostOrdersRefundHandle` * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not JSON + * @param response response body, NULL if not in JSON */ static void handle_refund_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WalletOrderRefundHandle *orh = cls; + struct TALER_MERCHANT_PostOrdersRefundHandle *porh = cls; const json_t *json = response; - struct TALER_MERCHANT_WalletRefundResponse wrr = { + struct TALER_MERCHANT_PostOrdersRefundResponse orr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - orh->job = NULL; + porh->job = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "POST /orders/$ID/refund completed with response code %u\n", + (unsigned int) response_code); switch (response_code) { case 0: - wrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + orr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_OK: { const json_t *refunds; unsigned int refund_len; struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_amount_any ( - "refund_amount", - &wrr.details.ok.refund_amount), GNUNET_JSON_spec_array_const ( "refunds", &refunds), GNUNET_JSON_spec_fixed_auto ( "merchant_pub", - &wrr.details.ok.merchant_pub), + &orr.details.ok.merchant_pub), GNUNET_JSON_spec_end () }; @@ -122,28 +142,29 @@ handle_refund_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); - wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - wrr.hr.http_status = 0; + orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + orr.hr.http_status = 0; break; } - refund_len = json_array_size (refunds); - if ( (json_array_size (refunds) != (size_t) refund_len) || + refund_len = (unsigned int) json_array_size (refunds); + if ( (json_array_size (refunds) != (size_t) refund_len) || (refund_len > MAX_REFUNDS) ) { GNUNET_break (0); - wrr.hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; - wrr.hr.http_status = 0; + orr.hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; + orr.hr.http_status = 0; break; } { - struct TALER_MERCHANT_RefundDetail rds[GNUNET_NZL (refund_len)]; + struct TALER_MERCHANT_PostOrdersRefundDetail rds[GNUNET_NZL ( + refund_len)]; memset (rds, 0, sizeof (rds)); - for (unsigned int i = 0; i<refund_len; i++) + for (unsigned int i = 0; i < refund_len; i++) { - struct TALER_MERCHANT_RefundDetail *rd = &rds[i]; + struct TALER_MERCHANT_PostOrdersRefundDetail *rd = &rds[i]; const json_t *jrefund = json_array_get (refunds, i); const char *refund_status_type; @@ -162,7 +183,7 @@ handle_refund_finished (void *cls, &rd->refund_amount), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_object_const ("exchange_reply", - &rd->hr.reply), + &rd->exchange_reply), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint32 ("exchange_code", @@ -177,22 +198,22 @@ handle_refund_finished (void *cls, NULL, NULL)) { GNUNET_break_op (0); - wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - wrr.hr.http_status = 0; + orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + orr.hr.http_status = 0; goto finish; } - rd->hr.http_status = exchange_status; - rd->hr.ec = (enum TALER_ErrorCode) eec; + rd->exchange_http_status = exchange_status; + rd->ec = (enum TALER_ErrorCode) eec; switch (exchange_status) { case MHD_HTTP_OK: { struct GNUNET_JSON_Specification rspec[] = { GNUNET_JSON_spec_fixed_auto ("exchange_sig", - &rd->details.ok.exchange_sig), + &rd->exchange_sig), GNUNET_JSON_spec_fixed_auto ("exchange_pub", - &rd->details.ok.exchange_pub), + &rd->exchange_pub), GNUNET_JSON_spec_end () }; @@ -203,143 +224,147 @@ handle_refund_finished (void *cls, NULL)) { GNUNET_break_op (0); - wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - wrr.hr.http_status = 0; + orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + orr.hr.http_status = 0; goto finish; } - /* check that type field is correct */ if (0 != strcmp ("success", refund_status_type)) { GNUNET_break_op (0); - wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - wrr.hr.http_status = 0; + orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + orr.hr.http_status = 0; goto finish; } } - break; /* end MHD_HTTP_OK */ + break; default: if (0 != strcmp ("failure", refund_status_type)) { GNUNET_break_op (0); - wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - wrr.hr.http_status = 0; + orr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + orr.hr.http_status = 0; goto finish; } - } /* switch on exchange status code */ - } /* for all refunds */ - - wrr.details.ok.refunds = rds; - wrr.details.ok.refunds_length = refund_len; - orh->cb (orh->cb_cls, - &wrr); - TALER_MERCHANT_wallet_post_order_refund_cancel (orh); + } + } + + orr.details.ok.refunds = rds; + orr.details.ok.num_refunds = refund_len; + porh->cb (porh->cb_cls, + &orr); + TALER_MERCHANT_post_orders_refund_cancel (porh); return; - } /* end 'rds' scope */ - } /* case MHD_HTTP_OK */ + } + } break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_CONFLICT: case MHD_HTTP_NOT_FOUND: - wrr.hr.ec = TALER_JSON_get_error_code (json); - wrr.hr.hint = TALER_JSON_get_error_hint (json); + orr.hr.ec = TALER_JSON_get_error_code (json); + orr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - GNUNET_break_op (0); /* unexpected status code */ + GNUNET_break_op (0); TALER_MERCHANT_parse_error_details_ (json, response_code, - &wrr.hr); + &orr.hr); break; } finish: - orh->cb (orh->cb_cls, - &wrr); - TALER_MERCHANT_wallet_post_order_refund_cancel (orh); + porh->cb (porh->cb_cls, + &orr); + TALER_MERCHANT_post_orders_refund_cancel (porh); } -struct TALER_MERCHANT_WalletOrderRefundHandle * -TALER_MERCHANT_wallet_post_order_refund ( +struct TALER_MERCHANT_PostOrdersRefundHandle * +TALER_MERCHANT_post_orders_refund_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *order_id, - const struct TALER_PrivateContractHashP *h_contract_terms, - TALER_MERCHANT_WalletRefundCallback cb, - void *cb_cls) + const struct TALER_PrivateContractHashP *h_contract_terms) +{ + struct TALER_MERCHANT_PostOrdersRefundHandle *porh; + + porh = GNUNET_new (struct TALER_MERCHANT_PostOrdersRefundHandle); + porh->ctx = ctx; + porh->base_url = GNUNET_strdup (url); + porh->order_id = GNUNET_strdup (order_id); + porh->h_contract_terms = *h_contract_terms; + return porh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_orders_refund_start ( + struct TALER_MERCHANT_PostOrdersRefundHandle *porh, + TALER_MERCHANT_PostOrdersRefundCallback cb, + TALER_MERCHANT_POST_ORDERS_REFUND_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_WalletOrderRefundHandle *orh; - json_t *req; + json_t *req_obj; CURL *eh; - orh = GNUNET_new (struct TALER_MERCHANT_WalletOrderRefundHandle); - orh->ctx = ctx; - orh->cb = cb; - orh->cb_cls = cb_cls; + porh->cb = cb; + porh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "orders/%s/refund", - order_id); - orh->url = TALER_url_join (backend_url, - path, - NULL); + porh->order_id); + porh->url = TALER_url_join (porh->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == orh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (orh); - return NULL; - } - req = GNUNET_JSON_PACK ( + if (NULL == porh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("h_contract", - h_contract_terms)); - eh = TALER_MERCHANT_curl_easy_get_ (orh->url); - if (GNUNET_OK != - TALER_curl_easy_post (&orh->post_ctx, - eh, - req)) + &porh->h_contract_terms)); + eh = TALER_MERCHANT_curl_easy_get_ (porh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&porh->post_ctx, + eh, + req_obj)) ) { GNUNET_break (0); - json_decref (req); - curl_easy_cleanup (eh); - GNUNET_free (orh->url); - GNUNET_free (orh); - return NULL; - } - json_decref (req); - orh->job = GNUNET_CURL_job_add2 (ctx, - eh, - orh->post_ctx.headers, - &handle_refund_finished, - orh); - if (NULL == orh->job) - { - GNUNET_free (orh->url); - GNUNET_free (orh); - return NULL; + json_decref (req_obj); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return orh; + json_decref (req_obj); + porh->job = GNUNET_CURL_job_add2 (porh->ctx, + eh, + porh->post_ctx.headers, + &handle_refund_finished, + porh); + if (NULL == porh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_wallet_post_order_refund_cancel ( - struct TALER_MERCHANT_WalletOrderRefundHandle *orh) +TALER_MERCHANT_post_orders_refund_cancel ( + struct TALER_MERCHANT_PostOrdersRefundHandle *porh) { - if (NULL != orh->job) + if (NULL != porh->job) { - GNUNET_CURL_job_cancel (orh->job); - orh->job = NULL; + GNUNET_CURL_job_cancel (porh->job); + porh->job = NULL; } - TALER_curl_easy_post_finished (&orh->post_ctx); - GNUNET_free (orh->url); - GNUNET_free (orh); + TALER_curl_easy_post_finished (&porh->post_ctx); + GNUNET_free (porh->order_id); + GNUNET_free (porh->url); + GNUNET_free (porh->base_url); + GNUNET_free (porh); } -/* end of merchant_api_wallet_post_order_refund.c */ +/* end of merchant_api_post-orders-ORDER_ID-refund-new.c */ diff --git a/src/lib/merchant_api_post-private-accounts-new.c b/src/lib/merchant_api_post-private-accounts-new.c @@ -1,298 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2023-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-accounts-new.c - * @brief Implementation of the POST /private/accounts request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-accounts-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/accounts operation. - */ -struct TALER_MERCHANT_PostPrivateAccountsHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateAccountsCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Payto URI to add. - */ - struct TALER_FullPayto payto_uri; - - /** - * Optional credit facade URL. - */ - const char *credit_facade_url; - - /** - * Optional credit facade credentials (JSON). - */ - const json_t *credit_facade_credentials; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/accounts request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateAccountsHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_account_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateAccountsHandle *pah = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateAccountsResponse apr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - pah->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/accounts completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - apr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("h_wire", - &apr.details.ok.h_wire), - GNUNET_JSON_spec_fixed_auto ("salt", - &apr.details.ok.salt), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - apr.hr.http_status = 0; - apr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - } - break; - case MHD_HTTP_BAD_REQUEST: - GNUNET_break_op (0); - apr.hr.ec = TALER_JSON_get_error_code (json); - apr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - apr.hr.ec = TALER_JSON_get_error_code (json); - apr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - apr.hr.ec = TALER_JSON_get_error_code (json); - apr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - apr.hr.ec = TALER_JSON_get_error_code (json); - apr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - apr.hr.ec = TALER_JSON_get_error_code (json); - apr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &apr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) apr.hr.ec); - GNUNET_break_op (0); - break; - } - pah->cb (pah->cb_cls, - &apr); - TALER_MERCHANT_post_private_accounts_cancel (pah); -} - - -struct TALER_MERCHANT_PostPrivateAccountsHandle * -TALER_MERCHANT_post_private_accounts_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - struct TALER_FullPayto payto_uri) -{ - struct TALER_MERCHANT_PostPrivateAccountsHandle *pah; - - pah = GNUNET_new (struct TALER_MERCHANT_PostPrivateAccountsHandle); - pah->ctx = ctx; - pah->base_url = GNUNET_strdup (url); - pah->payto_uri.full_payto = GNUNET_strdup (payto_uri.full_payto); - return pah; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_accounts_set_options_ ( - struct TALER_MERCHANT_PostPrivateAccountsHandle *pah, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateAccountsOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - 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; - break; - case TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS: - pah->credit_facade_credentials - = options[i].details.credit_facade_credentials; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_accounts_start ( - struct TALER_MERCHANT_PostPrivateAccountsHandle *pah, - TALER_MERCHANT_PostPrivateAccountsCallback cb, - TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - pah->cb = cb; - pah->cb_cls = cb_cls; - pah->url = TALER_url_join (pah->base_url, - "private/accounts", - NULL); - if (NULL == pah->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - TALER_JSON_pack_full_payto ( - "payto_uri", - pah->payto_uri), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ( - "credit_facade_url", - pah->credit_facade_url)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ( - "credit_facade_credentials", - (json_t *) pah->credit_facade_credentials)) - ); - eh = TALER_MERCHANT_curl_easy_get_ (pah->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pah->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - pah->job = GNUNET_CURL_job_add2 (pah->ctx, - eh, - pah->post_ctx.headers, - &handle_post_account_finished, - pah); - if (NULL == pah->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_accounts_cancel ( - struct TALER_MERCHANT_PostPrivateAccountsHandle *pah) -{ - if (NULL != pah->job) - { - GNUNET_CURL_job_cancel (pah->job); - pah->job = NULL; - } - TALER_curl_easy_post_finished (&pah->post_ctx); - GNUNET_free (pah->payto_uri.full_payto); - GNUNET_free (pah->url); - GNUNET_free (pah->base_url); - GNUNET_free (pah); -} - - -/* end of merchant_api_post-private-accounts-new.c */ diff --git a/src/lib/merchant_api_post-private-accounts.c b/src/lib/merchant_api_post-private-accounts.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2023 Taler Systems SA + Copyright (C) 2023-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-accounts.c - * @brief Implementation of the POST /account request - * of the merchant's HTTP API + * @file merchant_api_post-private-accounts-new.c + * @brief Implementation of the POST /private/accounts request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,7 +26,8 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-accounts.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -37,11 +37,15 @@ /** * Handle for a POST /private/accounts operation. */ -struct TALER_MERCHANT_AccountsPostHandle +struct TALER_MERCHANT_PostPrivateAccountsHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_AccountsPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_AccountsPostCallback cb; + TALER_MERCHANT_PostPrivateAccountsCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,28 @@ struct TALER_MERCHANT_AccountsPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Payto URI to add. + */ + struct TALER_FullPayto payto_uri; + + /** + * Optional credit facade URL. + */ + const char *credit_facade_url; + + /** + * Optional credit facade credentials (JSON). + */ + const json_t *credit_facade_credentials; }; /** * Function called when we're done processing the - * HTTP POST /account request. + * HTTP POST /private/accounts request. * - * @param cls the `struct TALER_MERCHANT_AccountPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateAccountsHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,16 +104,16 @@ handle_post_account_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_AccountsPostHandle *aph = cls; + struct TALER_MERCHANT_PostPrivateAccountsHandle *pah = cls; const json_t *json = response; - struct TALER_MERCHANT_AccountsPostResponse apr = { + struct TALER_MERCHANT_PostPrivateAccountsResponse apr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - aph->job = NULL; + pah->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /accounts completed with response code %u\n", + "POST /private/accounts completed with response code %u\n", (unsigned int) response_code); switch (response_code) { @@ -128,9 +146,6 @@ handle_post_account_finished (void *cls, GNUNET_break_op (0); apr.hr.ec = TALER_JSON_get_error_code (json); apr.hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ break; case MHD_HTTP_FORBIDDEN: apr.hr.ec = TALER_JSON_get_error_code (json); @@ -139,9 +154,6 @@ handle_post_account_finished (void *cls, case MHD_HTTP_NOT_FOUND: apr.hr.ec = TALER_JSON_get_error_code (json); apr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ break; case MHD_HTTP_CONFLICT: apr.hr.ec = TALER_JSON_get_error_code (json); @@ -150,14 +162,11 @@ handle_post_account_finished (void *cls, case MHD_HTTP_INTERNAL_SERVER_ERROR: apr.hr.ec = TALER_JSON_get_error_code (json); apr.hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, &apr.hr); - /* unexpected response code */ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, @@ -165,86 +174,125 @@ handle_post_account_finished (void *cls, GNUNET_break_op (0); break; } - aph->cb (aph->cb_cls, + pah->cb (pah->cb_cls, &apr); - TALER_MERCHANT_accounts_post_cancel (aph); + TALER_MERCHANT_post_private_accounts_cancel (pah); } -struct TALER_MERCHANT_AccountsPostHandle * -TALER_MERCHANT_accounts_post ( +struct TALER_MERCHANT_PostPrivateAccountsHandle * +TALER_MERCHANT_post_private_accounts_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - struct TALER_FullPayto payto_uri, - const char *credit_facade_url, - const json_t *credit_facade_credentials, - TALER_MERCHANT_AccountsPostCallback cb, - void *cb_cls) + const char *url, + struct TALER_FullPayto payto_uri) +{ + struct TALER_MERCHANT_PostPrivateAccountsHandle *pah; + + pah = GNUNET_new (struct TALER_MERCHANT_PostPrivateAccountsHandle); + pah->ctx = ctx; + pah->base_url = GNUNET_strdup (url); + pah->payto_uri.full_payto = GNUNET_strdup (payto_uri.full_payto); + return pah; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_accounts_set_options_ ( + struct TALER_MERCHANT_PostPrivateAccountsHandle *pah, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateAccountsOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + 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; + break; + case TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_OPTION_CREDIT_FACADE_CREDENTIALS: + pah->credit_facade_credentials + = options[i].details.credit_facade_credentials; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_accounts_start ( + struct TALER_MERCHANT_PostPrivateAccountsHandle *pah, + TALER_MERCHANT_PostPrivateAccountsCallback cb, + TALER_MERCHANT_POST_PRIVATE_ACCOUNTS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_AccountsPostHandle *aph; json_t *req_obj; + CURL *eh; + pah->cb = cb; + pah->cb_cls = cb_cls; + pah->url = TALER_url_join (pah->base_url, + "private/accounts", + NULL); + if (NULL == pah->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( TALER_JSON_pack_full_payto ( "payto_uri", - payto_uri), + pah->payto_uri), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ( "credit_facade_url", - credit_facade_url)), + pah->credit_facade_url)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ( "credit_facade_credentials", - (json_t *) credit_facade_credentials)) + (json_t *) pah->credit_facade_credentials)) ); - aph = GNUNET_new (struct TALER_MERCHANT_AccountsPostHandle); - aph->ctx = ctx; - aph->cb = cb; - aph->cb_cls = cb_cls; - aph->url = TALER_url_join (backend_url, - "private/accounts", - NULL); - if (NULL == aph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (aph); - return NULL; - } + eh = TALER_MERCHANT_curl_easy_get_ (pah->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pah->post_ctx, + eh, + req_obj)) ) { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (aph->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&aph->post_ctx, - eh, - req_obj)); + GNUNET_break (0); json_decref (req_obj); - aph->job = GNUNET_CURL_job_add2 (ctx, - eh, - aph->post_ctx.headers, - &handle_post_account_finished, - aph); - GNUNET_assert (NULL != aph->job); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return aph; + json_decref (req_obj); + pah->job = GNUNET_CURL_job_add2 (pah->ctx, + eh, + pah->post_ctx.headers, + &handle_post_account_finished, + pah); + if (NULL == pah->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_accounts_post_cancel ( - struct TALER_MERCHANT_AccountsPostHandle *aph) +TALER_MERCHANT_post_private_accounts_cancel ( + struct TALER_MERCHANT_PostPrivateAccountsHandle *pah) { - if (NULL != aph->job) + if (NULL != pah->job) { - GNUNET_CURL_job_cancel (aph->job); - aph->job = NULL; + GNUNET_CURL_job_cancel (pah->job); + pah->job = NULL; } - TALER_curl_easy_post_finished (&aph->post_ctx); - GNUNET_free (aph->url); - GNUNET_free (aph); + TALER_curl_easy_post_finished (&pah->post_ctx); + GNUNET_free (pah->payto_uri.full_payto); + GNUNET_free (pah->url); + GNUNET_free (pah->base_url); + GNUNET_free (pah); } -/* end of merchant_api_post_account.c */ +/* end of merchant_api_post-private-accounts-new.c */ diff --git a/src/lib/merchant_api_post-private-categories-new.c b/src/lib/merchant_api_post-private-categories-new.c @@ -1,286 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-categories-new.c - * @brief Implementation of the POST /private/categories request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-categories-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/categories operation. - */ -struct TALER_MERCHANT_PostPrivateCategoriesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateCategoriesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Human-readable name of the category. - */ - char *name; - - /** - * Optional internationalized names (JSON). - */ - const json_t *name_i18n; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/categories request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateCategoriesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_categories_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateCategoriesResponse cpr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppch->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/categories completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - cpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_uint64 ("category_id", - &cpr.details.ok.category_id), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - cpr.hr.http_status = 0; - cpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - } - break; - case MHD_HTTP_BAD_REQUEST: - cpr.hr.ec = TALER_JSON_get_error_code (json); - cpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - cpr.hr.ec = TALER_JSON_get_error_code (json); - cpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - cpr.hr.ec = TALER_JSON_get_error_code (json); - cpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - cpr.hr.ec = TALER_JSON_get_error_code (json); - cpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - cpr.hr.ec = TALER_JSON_get_error_code (json); - cpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - cpr.hr.ec = TALER_JSON_get_error_code (json); - cpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &cpr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) cpr.hr.ec); - GNUNET_break_op (0); - break; - } - ppch->cb (ppch->cb_cls, - &cpr); - TALER_MERCHANT_post_private_categories_cancel (ppch); -} - - -struct TALER_MERCHANT_PostPrivateCategoriesHandle * -TALER_MERCHANT_post_private_categories_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *name) -{ - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch; - - ppch = GNUNET_new (struct TALER_MERCHANT_PostPrivateCategoriesHandle); - ppch->ctx = ctx; - ppch->base_url = GNUNET_strdup (url); - ppch->name = GNUNET_strdup (name); - return ppch; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_categories_set_options_ ( - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N: - ppch->name_i18n = options[i].details.name_i18n; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_categories_start ( - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, - TALER_MERCHANT_PostPrivateCategoriesCallback cb, - TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppch->cb = cb; - ppch->cb_cls = cb_cls; - ppch->url = TALER_url_join (ppch->base_url, - "private/categories", - NULL); - if (NULL == ppch->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ( - "name", - ppch->name), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ( - "name_i18n", - (json_t *) ppch->name_i18n)) - ); - eh = TALER_MERCHANT_curl_easy_get_ (ppch->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppch->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppch->job = GNUNET_CURL_job_add2 (ppch->ctx, - eh, - ppch->post_ctx.headers, - &handle_post_categories_finished, - ppch); - if (NULL == ppch->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_categories_cancel ( - struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch) -{ - if (NULL != ppch->job) - { - GNUNET_CURL_job_cancel (ppch->job); - ppch->job = NULL; - } - TALER_curl_easy_post_finished (&ppch->post_ctx); - GNUNET_free (ppch->name); - GNUNET_free (ppch->url); - GNUNET_free (ppch->base_url); - GNUNET_free (ppch); -} - - -/* end of merchant_api_post-private-categories-new.c */ diff --git a/src/lib/merchant_api_post-private-categories.c b/src/lib/merchant_api_post-private-categories.c @@ -1,223 +1,286 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free - Software Foundation; either version 2.1, or (at your option) any later version. + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1, + or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with TALER; see the file COPYING.LGPL. + You should have received a copy of the GNU Lesser General + Public License along with TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-categories.c - * @brief Implementation of POST /private/categories - * @author Bohdan Potuzhnyi + * @file merchant_api_post-private-categories-new.c + * @brief Implementation of the POST /private/categories request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-categories.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> + /** * Handle for a POST /private/categories operation. */ -struct TALER_MERCHANT_CategoriesPostHandle +struct TALER_MERCHANT_PostPrivateCategoriesHandle { /** - * Fully qualified request URL. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * CURL job handle. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** - * Callback to invoke with the result. + * Function to call with the result. */ - TALER_MERCHANT_CategoriesPostCallback cb; + TALER_MERCHANT_PostPrivateCategoriesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cb_cls; /** - * Execution context. + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; /** - * Helper keeping POST body and headers alive. + * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Human-readable name of the category. + */ + char *name; + + /** + * Optional internationalized names (JSON). + */ + const json_t *name_i18n; }; + /** - * Called when the HTTP transfer finishes. + * Function called when we're done processing the + * HTTP POST /private/categories request. * - * @param cls operation handle - * @param response_code HTTP status (0 on network / parsing failures) - * @param response parsed JSON reply (NULL if unavailable) + * @param cls the `struct TALER_MERCHANT_PostPrivateCategoriesHandle` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON */ static void handle_post_categories_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_CategoriesPostHandle *cph = cls; + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch = cls; const json_t *json = response; - struct TALER_MERCHANT_CategoriesPostResponse cpr = { + struct TALER_MERCHANT_PostPrivateCategoriesResponse cpr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - cph->job = NULL; + ppch->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/categories completed with status %u\n", + "POST /private/categories completed with response code %u\n", (unsigned int) response_code); switch (response_code) { + case 0: + cpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; case MHD_HTTP_OK: { - const char *err_name; - unsigned int err_line; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_uint64 ("category_id", - &cpr.category_id), + &cpr.details.ok.category_id), GNUNET_JSON_spec_end () }; if (GNUNET_OK != GNUNET_JSON_parse (json, spec, - &err_name, - &err_line)) + NULL, NULL)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid response for field %s\n", - err_name); + GNUNET_break_op (0); cpr.hr.http_status = 0; cpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; } - break; } + break; case MHD_HTTP_BAD_REQUEST: + cpr.hr.ec = TALER_JSON_get_error_code (json); + cpr.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_UNAUTHORIZED: + cpr.hr.ec = TALER_JSON_get_error_code (json); + cpr.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_FORBIDDEN: + cpr.hr.ec = TALER_JSON_get_error_code (json); + cpr.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_NOT_FOUND: + cpr.hr.ec = TALER_JSON_get_error_code (json); + cpr.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_CONFLICT: - case MHD_HTTP_INTERNAL_SERVER_ERROR: cpr.hr.ec = TALER_JSON_get_error_code (json); cpr.hr.hint = TALER_JSON_get_error_hint (json); break; - case 0: - cpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + case MHD_HTTP_INTERNAL_SERVER_ERROR: + cpr.hr.ec = TALER_JSON_get_error_code (json); + cpr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, &cpr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response %u/%d for POST /private/categories\n", + "Unexpected response code %u/%d\n", (unsigned int) response_code, (int) cpr.hr.ec); GNUNET_break_op (0); break; } - cph->cb (cph->cb_cls, - &cpr); - TALER_MERCHANT_categories_post_cancel (cph); + ppch->cb (ppch->cb_cls, + &cpr); + TALER_MERCHANT_post_private_categories_cancel (ppch); } -struct TALER_MERCHANT_CategoriesPostHandle * -TALER_MERCHANT_categories_post ( +struct TALER_MERCHANT_PostPrivateCategoriesHandle * +TALER_MERCHANT_post_private_categories_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *name, - const json_t *name_i18n, - TALER_MERCHANT_CategoriesPostCallback cb, - void *cb_cls) + const char *url, + const char *name) +{ + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch; + + ppch = GNUNET_new (struct TALER_MERCHANT_PostPrivateCategoriesHandle); + ppch->ctx = ctx; + ppch->base_url = GNUNET_strdup (url); + ppch->name = GNUNET_strdup (name); + return ppch; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_categories_set_options_ ( + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateCategoriesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_CATEGORIES_OPTION_NAME_I18N: + ppch->name_i18n = options[i].details.name_i18n; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_categories_start ( + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch, + TALER_MERCHANT_PostPrivateCategoriesCallback cb, + TALER_MERCHANT_POST_PRIVATE_CATEGORIES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_CategoriesPostHandle *cph; json_t *req_obj; + CURL *eh; + ppch->cb = cb; + ppch->cb_cls = cb_cls; + ppch->url = TALER_url_join (ppch->base_url, + "private/categories", + NULL); + if (NULL == ppch->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("name", - name), + GNUNET_JSON_pack_string ( + "name", + ppch->name), GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("name_i18n", - (json_t *) name_i18n))); - cph = GNUNET_new (struct TALER_MERCHANT_CategoriesPostHandle); - cph->ctx = ctx; - cph->cb = cb; - cph->cb_cls = cb_cls; - cph->url = TALER_url_join (backend_url, - "private/categories", - NULL); - if (NULL == cph->url) + GNUNET_JSON_pack_object_incref ( + "name_i18n", + (json_t *) ppch->name_i18n)) + ); + eh = TALER_MERCHANT_curl_easy_get_ (ppch->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppch->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to build /private/categories URL\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (cph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (cph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&cph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (cph->url); - GNUNET_free (cph); - return NULL; - } - json_decref (req_obj); - cph->job = GNUNET_CURL_job_add2 (ctx, - eh, - cph->post_ctx.headers, - &handle_post_categories_finished, - cph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return cph; + json_decref (req_obj); + ppch->job = GNUNET_CURL_job_add2 (ppch->ctx, + eh, + ppch->post_ctx.headers, + &handle_post_categories_finished, + ppch); + if (NULL == ppch->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_categories_post_cancel ( - struct TALER_MERCHANT_CategoriesPostHandle *cph) +TALER_MERCHANT_post_private_categories_cancel ( + struct TALER_MERCHANT_PostPrivateCategoriesHandle *ppch) { - if (NULL != cph->job) + if (NULL != ppch->job) { - GNUNET_CURL_job_cancel (cph->job); - cph->job = NULL; + GNUNET_CURL_job_cancel (ppch->job); + ppch->job = NULL; } - TALER_curl_easy_post_finished (&cph->post_ctx); - GNUNET_free (cph->url); - GNUNET_free (cph); + TALER_curl_easy_post_finished (&ppch->post_ctx); + GNUNET_free (ppch->name); + GNUNET_free (ppch->url); + GNUNET_free (ppch->base_url); + GNUNET_free (ppch); } -/* end of merchant_api_post_categories.c */ +/* end of merchant_api_post-private-categories-new.c */ diff --git a/src/lib/merchant_api_post-private-donau-new.c b/src/lib/merchant_api_post-private-donau-new.c @@ -1,256 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2024-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-donau-new.c - * @brief Implementation of the POST /private/donau request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-donau-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/donau operation. - */ -struct TALER_MERCHANT_PostPrivateDonauHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateDonauCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Charity information to register. - */ - struct TALER_MERCHANT_Charity charity; - - /** - * Charity URL (owned copy). - */ - char *charity_url; - - /** - * Optional authentication token. - */ - const char *auth_token; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/donau request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateDonauHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_donau_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateDonauResponse pdr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppdh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/donau completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - pdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - pdr.hr.ec = TALER_JSON_get_error_code (json); - pdr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - pdr.hr.ec = TALER_JSON_get_error_code (json); - pdr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pdr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pdr.hr.ec); - GNUNET_break_op (0); - break; - } - ppdh->cb (ppdh->cb_cls, - &pdr); - TALER_MERCHANT_post_private_donau_cancel (ppdh); -} - - -struct TALER_MERCHANT_PostPrivateDonauHandle * -TALER_MERCHANT_post_private_donau_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_MERCHANT_Charity *charity) -{ - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh; - - ppdh = GNUNET_new (struct TALER_MERCHANT_PostPrivateDonauHandle); - ppdh->ctx = ctx; - ppdh->base_url = GNUNET_strdup (url); - ppdh->charity_url = GNUNET_strdup (charity->charity_url); - ppdh->charity.charity_url = ppdh->charity_url; - ppdh->charity.charity_id = charity->charity_id; - return ppdh; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_donau_set_options_ ( - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateDonauOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN: - ppdh->auth_token = options[i].details.auth_token; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_donau_start ( - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, - TALER_MERCHANT_PostPrivateDonauCallback cb, - TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppdh->cb = cb; - ppdh->cb_cls = cb_cls; - ppdh->url = TALER_url_join (ppdh->base_url, - "private/donau", - NULL); - if (NULL == ppdh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("donau_url", - ppdh->charity.charity_url), - GNUNET_JSON_pack_uint64 ("charity_id", - ppdh->charity.charity_id) - ); - eh = TALER_MERCHANT_curl_easy_get_ (ppdh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppdh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppdh->job = GNUNET_CURL_job_add2 (ppdh->ctx, - eh, - ppdh->post_ctx.headers, - &handle_post_donau_finished, - ppdh); - if (NULL == ppdh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_donau_cancel ( - struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh) -{ - if (NULL != ppdh->job) - { - GNUNET_CURL_job_cancel (ppdh->job); - ppdh->job = NULL; - } - TALER_curl_easy_post_finished (&ppdh->post_ctx); - GNUNET_free (ppdh->charity_url); - GNUNET_free (ppdh->url); - GNUNET_free (ppdh->base_url); - GNUNET_free (ppdh); -} - - -/* end of merchant_api_post-private-donau-new.c */ diff --git a/src/lib/merchant_api_post-private-donau.c b/src/lib/merchant_api_post-private-donau.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2024 Taler Systems SA + Copyright (C) 2024-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,53 +17,52 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-donau.c - * @brief Implementation of the POST /donau request - * of the merchant's HTTP API - * @author Bohdan Potuzhnyi - * @author Vlada Svirsh + * @file merchant_api_post-private-donau-new.c + * @brief Implementation of the POST /private/donau request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-donau.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> -#include <taler/taler_kyclogic_lib.h> -/* DONAU RELATED IMPORTS */ -#include "taler/taler_merchant_donau.h" -#include <donau/donau_service.h> /** - * Handle for a POST /donau operation. + * Handle for a POST /private/donau operation. */ -struct TALER_MERCHANT_DonauInstancePostHandle +struct TALER_MERCHANT_PostPrivateDonauHandle { /** - * URL for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * Handle for the CURL job. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** * Function to call with the result. */ - TALER_MERCHANT_DonauInstancePostCallback cb; + TALER_MERCHANT_PostPrivateDonauCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -74,13 +73,29 @@ struct TALER_MERCHANT_DonauInstancePostHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Charity information to register. + */ + struct TALER_MERCHANT_Charity charity; + + /** + * Charity URL (owned copy). + */ + char *charity_url; + + /** + * Optional authentication token. + */ + const char *auth_token; }; /** - * Function called when the POST /donau operation is finished. + * Function called when we're done processing the + * HTTP POST /private/donau request. * - * @param cls the `struct TALER_MERCHANT_DonauInstancePostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateDonauHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -89,149 +104,153 @@ handle_post_donau_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_DonauInstancePostHandle *dph = cls; + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateDonauResponse pdr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - dph->job = NULL; + ppdh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /donau completed with response code %u\n", + "POST /private/donau completed with response code %u\n", (unsigned int) response_code); - switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + pdr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: + pdr.hr.ec = TALER_JSON_get_error_code (json); + pdr.hr.hint = TALER_JSON_get_error_hint (json); + break; case MHD_HTTP_INTERNAL_SERVER_ERROR: + pdr.hr.ec = TALER_JSON_get_error_code (json); + pdr.hr.hint = TALER_JSON_get_error_hint (json); + break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); + &pdr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) pdr.hr.ec); + GNUNET_break_op (0); break; } - - dph->cb (dph->cb_cls, - &hr); - TALER_MERCHANT_donau_instances_post_cancel (dph); + ppdh->cb (ppdh->cb_cls, + &pdr); + TALER_MERCHANT_post_private_donau_cancel (ppdh); } -struct TALER_MERCHANT_DonauInstancePostHandle * -TALER_MERCHANT_donau_instances_post ( +struct TALER_MERCHANT_PostPrivateDonauHandle * +TALER_MERCHANT_post_private_donau_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct TALER_MERCHANT_Charity *charity, - const char *auth_token, - TALER_MERCHANT_DonauInstancePostCallback cb, - void *cb_cls) + const char *url, + const struct TALER_MERCHANT_Charity *charity) { - struct TALER_MERCHANT_DonauInstancePostHandle *dph; - json_t *req_obj; - json_t *auth_obj; + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh; - if (NULL != auth_token) + ppdh = GNUNET_new (struct TALER_MERCHANT_PostPrivateDonauHandle); + ppdh->ctx = ctx; + ppdh->base_url = GNUNET_strdup (url); + ppdh->charity_url = GNUNET_strdup (charity->charity_url); + ppdh->charity.charity_url = ppdh->charity_url; + ppdh->charity.charity_id = charity->charity_id; + return ppdh; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_donau_set_options_ ( + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateDonauOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) { - if (0 != strncasecmp (RFC_8959_PREFIX, - auth_token, - strlen (RFC_8959_PREFIX))) + switch (options[i].option) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Authentication token must start with `%s'\n", - RFC_8959_PREFIX); - return NULL; + case TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_DONAU_OPTION_AUTH_TOKEN: + ppdh->auth_token = options[i].details.auth_token; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; } - auth_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("method", - "token"), - GNUNET_JSON_pack_string ("token", - auth_token)); - } - else - { - auth_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("method", - "external")); - } - if (NULL == auth_obj) - { - GNUNET_break (0); - return NULL; } + return GNUNET_OK; +} + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_donau_start ( + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh, + TALER_MERCHANT_PostPrivateDonauCallback cb, + TALER_MERCHANT_POST_PRIVATE_DONAU_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + + ppdh->cb = cb; + ppdh->cb_cls = cb_cls; + ppdh->url = TALER_url_join (ppdh->base_url, + "private/donau", + NULL); + if (NULL == ppdh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("donau_url", - charity->charity_url), + ppdh->charity.charity_url), GNUNET_JSON_pack_uint64 ("charity_id", - charity->charity_id) + ppdh->charity.charity_id) ); - - dph = GNUNET_new (struct TALER_MERCHANT_DonauInstancePostHandle); - dph->ctx = ctx; - dph->cb = cb; - dph->cb_cls = cb_cls; - dph->url = TALER_url_join (backend_url, - "private/donau", - NULL); - - if (NULL == dph->url) + eh = TALER_MERCHANT_curl_easy_get_ (ppdh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppdh->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to construct request URL\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (dph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (dph->url); - if (GNUNET_OK != TALER_curl_easy_post (&dph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (dph); - return NULL; - } - - json_decref (req_obj); - - dph->job = GNUNET_CURL_job_add2 (ctx, - eh, - dph->post_ctx.headers, - &handle_post_donau_finished, - dph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return dph; + json_decref (req_obj); + ppdh->job = GNUNET_CURL_job_add2 (ppdh->ctx, + eh, + ppdh->post_ctx.headers, + &handle_post_donau_finished, + ppdh); + if (NULL == ppdh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_donau_instances_post_cancel ( - struct TALER_MERCHANT_DonauInstancePostHandle *dph) +TALER_MERCHANT_post_private_donau_cancel ( + struct TALER_MERCHANT_PostPrivateDonauHandle *ppdh) { - if (NULL != dph->job) + if (NULL != ppdh->job) { - GNUNET_CURL_job_cancel (dph->job); - dph->job = NULL; + GNUNET_CURL_job_cancel (ppdh->job); + ppdh->job = NULL; } - TALER_curl_easy_post_finished (&dph->post_ctx); - GNUNET_free (dph->url); - GNUNET_free (dph); + TALER_curl_easy_post_finished (&ppdh->post_ctx); + GNUNET_free (ppdh->charity_url); + GNUNET_free (ppdh->url); + GNUNET_free (ppdh->base_url); + GNUNET_free (ppdh); } -/* end of merchant_api_post_donau_instance.c */ +/* end of merchant_api_post-private-donau-new.c */ diff --git a/src/lib/merchant_api_post-private-orders-ORDER_ID-refund-new.c b/src/lib/merchant_api_post-private-orders-ORDER_ID-refund-new.c @@ -1,267 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-orders-ORDER_ID-refund-new.c - * @brief Implementation of the POST /private/orders/$ORDER_ID/refund request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/orders/$ORDER_ID/refund operation. - */ -struct TALER_MERCHANT_PostPrivateOrdersRefundHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateOrdersRefundCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Identifier of the order to refund. - */ - char *order_id; - - /** - * Amount to refund. - */ - struct TALER_Amount refund; - - /** - * Human-readable reason for the refund. - */ - char *reason; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/orders/$ORDER_ID/refund request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateOrdersRefundHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_refund_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateOrdersRefundResponse rr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - porh->job = NULL; - switch (response_code) - { - case 0: - rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ( - "taler_refund_uri", - &rr.details.ok.taler_refund_uri), - GNUNET_JSON_spec_fixed_auto ( - "h_contract", - &rr.details.ok.h_contract), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - rr.hr.http_status = 0; - rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - } - break; - } - case MHD_HTTP_UNAUTHORIZED: - rr.hr.ec = TALER_JSON_get_error_code (json); - rr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - rr.hr.ec = TALER_JSON_get_error_code (json); - rr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - rr.hr.ec = TALER_JSON_get_error_code (json); - rr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - rr.hr.ec = TALER_JSON_get_error_code (json); - rr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_GONE: - rr.hr.ec = TALER_JSON_get_error_code (json); - rr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - GNUNET_break_op (0); - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &rr.hr); - break; - } - porh->cb (porh->cb_cls, - &rr); - TALER_MERCHANT_post_private_orders_refund_cancel (porh); -} - - -struct TALER_MERCHANT_PostPrivateOrdersRefundHandle * -TALER_MERCHANT_post_private_orders_refund_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *order_id, - const struct TALER_Amount *refund, - const char *reason) -{ - struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh; - - porh = GNUNET_new (struct TALER_MERCHANT_PostPrivateOrdersRefundHandle); - porh->ctx = ctx; - porh->base_url = GNUNET_strdup (url); - porh->order_id = GNUNET_strdup (order_id); - porh->refund = *refund; - porh->reason = GNUNET_strdup (reason); - return porh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_orders_refund_start ( - struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh, - TALER_MERCHANT_PostPrivateOrdersRefundCallback cb, - TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - porh->cb = cb; - porh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/orders/%s/refund", - porh->order_id); - porh->url = TALER_url_join (porh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == porh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("refund", - &porh->refund), - GNUNET_JSON_pack_string ("reason", - porh->reason)); - eh = TALER_MERCHANT_curl_easy_get_ (porh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&porh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - porh->job = GNUNET_CURL_job_add2 (porh->ctx, - eh, - porh->post_ctx.headers, - &handle_refund_finished, - porh); - if (NULL == porh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_orders_refund_cancel ( - struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh) -{ - if (NULL != porh->job) - { - GNUNET_CURL_job_cancel (porh->job); - porh->job = NULL; - } - TALER_curl_easy_post_finished (&porh->post_ctx); - GNUNET_free (porh->order_id); - GNUNET_free (porh->reason); - GNUNET_free (porh->url); - GNUNET_free (porh->base_url); - GNUNET_free (porh); -} - - -/* end of merchant_api_post-private-orders-ORDER_ID-refund-new.c */ diff --git a/src/lib/merchant_api_post-private-orders-ORDER_ID-refund.c b/src/lib/merchant_api_post-private-orders-ORDER_ID-refund.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -15,10 +15,9 @@ <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-orders-ORDER_ID-refund.c - * @brief Implementation of the POST /orders/ID/refund request + * @file merchant_api_post-private-orders-ORDER_ID-refund-new.c + * @brief Implementation of the POST /private/orders/$ORDER_ID/refund request * @author Christian Grothoff - * @author Marcello Stanisci */ #include "taler/platform.h" #include <curl/curl.h> @@ -26,71 +25,91 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-private-orders-ORDER_ID-refund.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> /** - * Handle for a POST /orders/ID/refund operation. + * Handle for a POST /private/orders/$ORDER_ID/refund operation. */ -struct TALER_MERCHANT_OrderRefundHandle +struct TALER_MERCHANT_PostPrivateOrdersRefundHandle { /** - * Complete URL where the backend offers /refund + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * Minor context that holds body and headers. + * Handle for the request. */ - struct TALER_CURL_PostContext post_ctx; + struct GNUNET_CURL_Job *job; /** - * The CURL context to connect to the backend + * Function to call with the result. + */ + TALER_MERCHANT_PostPrivateOrdersRefundCallback cb; + + /** + * Closure for @a cb. + */ + TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cb_cls; + + /** + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; /** - * The callback to pass the backend response to + * Minor context that holds body and headers. */ - TALER_MERCHANT_RefundCallback cb; + struct TALER_CURL_PostContext post_ctx; /** - * Clasure to pass to the callback + * Identifier of the order to refund. */ - void *cb_cls; + char *order_id; /** - * Handle for the request + * Amount to refund. */ - struct GNUNET_CURL_Job *job; + struct TALER_Amount refund; + + /** + * Human-readable reason for the refund. + */ + char *reason; }; /** - * Callback to process POST /orders/ID/refund response + * Function called when we're done processing the + * HTTP POST /private/orders/$ORDER_ID/refund request. * - * @param cls the `struct TALER_MERCHANT_OrderRefundHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateOrdersRefundHandle` * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not JSON + * @param response response body, NULL if not in JSON */ static void handle_refund_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OrderRefundHandle *orh = cls; + struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh = cls; const json_t *json = response; - struct TALER_MERCHANT_RefundResponse rr = { + struct TALER_MERCHANT_PostPrivateOrdersRefundResponse rr = { .hr.http_status = (unsigned int) response_code, .hr.reply = json }; - orh->job = NULL; + porh->job = NULL; switch (response_code) { case 0: @@ -123,124 +142,126 @@ handle_refund_finished (void *cls, case MHD_HTTP_UNAUTHORIZED: rr.hr.ec = TALER_JSON_get_error_code (json); rr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_FORBIDDEN: rr.hr.ec = TALER_JSON_get_error_code (json); rr.hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ break; case MHD_HTTP_NOT_FOUND: - /* order unknown (or not paid) */ rr.hr.ec = TALER_JSON_get_error_code (json); rr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - /* amount not acceptable */ rr.hr.ec = TALER_JSON_get_error_code (json); rr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_GONE: - /* too late, wire deadline is past */ rr.hr.ec = TALER_JSON_get_error_code (json); rr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - GNUNET_break_op (0); /* unexpected status code */ + GNUNET_break_op (0); TALER_MERCHANT_parse_error_details_ (json, response_code, &rr.hr); break; } - orh->cb (orh->cb_cls, - &rr); - TALER_MERCHANT_post_order_refund_cancel (orh); + porh->cb (porh->cb_cls, + &rr); + TALER_MERCHANT_post_private_orders_refund_cancel (porh); } -void -TALER_MERCHANT_post_order_refund_cancel ( - struct TALER_MERCHANT_OrderRefundHandle *orh) +struct TALER_MERCHANT_PostPrivateOrdersRefundHandle * +TALER_MERCHANT_post_private_orders_refund_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *order_id, + const struct TALER_Amount *refund, + const char *reason) { - if (NULL != orh->job) - { - GNUNET_CURL_job_cancel (orh->job); - orh->job = NULL; - } - TALER_curl_easy_post_finished (&orh->post_ctx); - GNUNET_free (orh->url); - GNUNET_free (orh); + struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh; + + porh = GNUNET_new (struct TALER_MERCHANT_PostPrivateOrdersRefundHandle); + porh->ctx = ctx; + porh->base_url = GNUNET_strdup (url); + porh->order_id = GNUNET_strdup (order_id); + porh->refund = *refund; + porh->reason = GNUNET_strdup (reason); + return porh; } -struct TALER_MERCHANT_OrderRefundHandle * -TALER_MERCHANT_post_order_refund (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct TALER_Amount *refund, - const char *reason, - TALER_MERCHANT_RefundCallback cb, - void *cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_post_private_orders_refund_start ( + struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh, + TALER_MERCHANT_PostPrivateOrdersRefundCallback cb, + TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OrderRefundHandle *orh; - json_t *req; + json_t *req_obj; CURL *eh; - orh = GNUNET_new (struct TALER_MERCHANT_OrderRefundHandle); - orh->ctx = ctx; - orh->cb = cb; - orh->cb_cls = cb_cls; + porh->cb = cb; + porh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/orders/%s/refund", - order_id); - orh->url = TALER_url_join (backend_url, - path, - NULL); + porh->order_id); + porh->url = TALER_url_join (porh->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == orh->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (orh); - return NULL; - } - req = GNUNET_JSON_PACK ( + if (NULL == porh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( TALER_JSON_pack_amount ("refund", - refund), + &porh->refund), GNUNET_JSON_pack_string ("reason", - reason)); - GNUNET_assert (NULL != req); - eh = TALER_MERCHANT_curl_easy_get_ (orh->url); - if (GNUNET_OK != - TALER_curl_easy_post (&orh->post_ctx, - eh, - req)) + porh->reason)); + eh = TALER_MERCHANT_curl_easy_get_ (porh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&porh->post_ctx, + eh, + req_obj)) ) { GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req); - GNUNET_free (orh->url); - GNUNET_free (orh); - return NULL; + json_decref (req_obj); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - json_decref (req); - orh->job = GNUNET_CURL_job_add2 (ctx, - eh, - orh->post_ctx.headers, - &handle_refund_finished, - orh); - if (NULL == orh->job) + json_decref (req_obj); + porh->job = GNUNET_CURL_job_add2 (porh->ctx, + eh, + porh->post_ctx.headers, + &handle_refund_finished, + porh); + if (NULL == porh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; +} + + +void +TALER_MERCHANT_post_private_orders_refund_cancel ( + struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *porh) +{ + if (NULL != porh->job) { - GNUNET_free (orh->url); - GNUNET_free (orh); - return NULL; + GNUNET_CURL_job_cancel (porh->job); + porh->job = NULL; } - return orh; + TALER_curl_easy_post_finished (&porh->post_ctx); + GNUNET_free (porh->order_id); + GNUNET_free (porh->reason); + GNUNET_free (porh->url); + GNUNET_free (porh->base_url); + GNUNET_free (porh); } -/* end of merchant_api_post_order_refund.c */ +/* end of merchant_api_post-private-orders-ORDER_ID-refund-new.c */ diff --git a/src/lib/merchant_api_post-private-orders-new.c b/src/lib/merchant_api_post-private-orders-new.c @@ -1,510 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-orders-new.c - * @brief Implementation of the POST /private/orders request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-orders-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/orders operation. - */ -struct TALER_MERCHANT_PostPrivateOrdersHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateOrdersCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Order contract terms (JSON). - */ - json_t *order; - - /** - * Optional refund delay. - */ - struct GNUNET_TIME_Relative refund_delay; - - /** - * Whether refund_delay was set. - */ - bool refund_delay_set; - - /** - * Optional payment target. - */ - const char *payment_target; - - /** - * Optional session ID. - */ - const char *session_id; - - /** - * Whether to create a claim token (default: true). - */ - bool create_token; - - /** - * Whether create_token was explicitly set. - */ - bool create_token_set; - - /** - * Optional OTP device ID. - */ - const char *otp_id; - - /** - * Optional inventory products. - */ - const struct TALER_MERCHANT_PostPrivateOrdersInventoryProduct * - inventory_products; - - /** - * Number of inventory products. - */ - unsigned int num_inventory_products; - - /** - * Optional lock UUIDs. - */ - const char **lock_uuids; - - /** - * Number of lock UUIDs. - */ - unsigned int num_lock_uuids; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/orders request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateOrdersHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_orders_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateOrdersResponse por = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - struct TALER_ClaimTokenP token; - - ppoh->job = NULL; - switch (response_code) - { - case 0: - por.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - { - bool no_token; - bool no_pay_deadline; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("order_id", - &por.details.ok.order_id), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_fixed_auto ("token", - &token), - &no_token), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ("pay_deadline", - &por.details.ok.pay_deadline), - &no_pay_deadline), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - por.hr.http_status = 0; - por.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - break; - } - if (! no_token) - por.details.ok.token = &token; - if (no_pay_deadline) - por.details.ok.pay_deadline = GNUNET_TIME_UNIT_ZERO_TS; - break; - } - case MHD_HTTP_BAD_REQUEST: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_GONE: - { - bool rq_frac_missing; - bool aq_frac_missing; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ( - "product_id", - &por.details.gone.product_id), - GNUNET_JSON_spec_uint64 ( - "requested_quantity", - &por.details.gone.requested_quantity), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ( - "requested_quantity_frac", - &por.details.gone.requested_quantity_frac), - &rq_frac_missing), - GNUNET_JSON_spec_uint64 ( - "available_quantity", - &por.details.gone.available_quantity), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ( - "available_quantity_frac", - &por.details.gone.available_quantity_frac), - &aq_frac_missing), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ( - "restock_expected", - &por.details.gone.restock_expected), - NULL), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - por.hr.http_status = 0; - por.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - } - else - { - if (rq_frac_missing) - por.details.gone.requested_quantity_frac = 0; - if (aq_frac_missing) - por.details.gone.available_quantity_frac = 0; - } - break; - } - case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - por.hr.ec = TALER_JSON_get_error_code (json); - por.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) por.hr.ec); - GNUNET_break_op (0); - break; - } - ppoh->cb (ppoh->cb_cls, - &por); - TALER_MERCHANT_post_private_orders_cancel (ppoh); -} - - -struct TALER_MERCHANT_PostPrivateOrdersHandle * -TALER_MERCHANT_post_private_orders_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const json_t *order) -{ - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh; - - ppoh = GNUNET_new (struct TALER_MERCHANT_PostPrivateOrdersHandle); - ppoh->ctx = ctx; - ppoh->base_url = GNUNET_strdup (url); - ppoh->order = json_incref ((json_t *) order); - return ppoh; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_orders_set_options_ ( - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateOrdersOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY: - ppoh->refund_delay = options[i].details.refund_delay; - ppoh->refund_delay_set = true; - break; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET: - ppoh->payment_target = options[i].details.payment_target; - break; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID: - ppoh->session_id = options[i].details.session_id; - break; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN: - ppoh->create_token = options[i].details.create_token; - ppoh->create_token_set = true; - break; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID: - ppoh->otp_id = options[i].details.otp_id; - break; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS: - ppoh->num_inventory_products - = options[i].details.inventory_products.num; - ppoh->inventory_products - = options[i].details.inventory_products.products; - break; - case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS: - ppoh->num_lock_uuids = options[i].details.lock_uuids.num; - ppoh->lock_uuids = options[i].details.lock_uuids.uuids; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_orders_start ( - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, - TALER_MERCHANT_PostPrivateOrdersCallback cb, - TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls) -{ - json_t *req; - CURL *eh; - - ppoh->cb = cb; - ppoh->cb_cls = cb_cls; - ppoh->url = TALER_url_join (ppoh->base_url, - "private/orders", - NULL); - if (NULL == ppoh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_object_incref ("order", - ppoh->order), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("session_id", - ppoh->session_id)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("payment_target", - ppoh->payment_target)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("otp_id", - ppoh->otp_id))); - if (ppoh->refund_delay_set && - (0 != ppoh->refund_delay.rel_value_us)) - { - GNUNET_assert (0 == - json_object_set_new (req, - "refund_delay", - GNUNET_JSON_from_time_rel ( - ppoh->refund_delay))); - } - if (0 != ppoh->num_inventory_products) - { - json_t *ipa = json_array (); - - GNUNET_assert (NULL != ipa); - for (unsigned int i = 0; i < ppoh->num_inventory_products; i++) - { - json_t *ip; - - if (ppoh->inventory_products[i].use_fractional_quantity) - { - char unit_quantity_buf[64]; - - TALER_MERCHANT_format_quantity_string ( - ppoh->inventory_products[i].quantity, - ppoh->inventory_products[i].quantity_frac, - unit_quantity_buf, - sizeof (unit_quantity_buf)); - ip = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("product_id", - ppoh->inventory_products[i].product_id), - GNUNET_JSON_pack_string ("unit_quantity", - unit_quantity_buf)); - } - else - { - char unit_quantity_buf[64]; - - TALER_MERCHANT_format_quantity_string ( - ppoh->inventory_products[i].quantity, - 0, - unit_quantity_buf, - sizeof (unit_quantity_buf)); - ip = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("product_id", - ppoh->inventory_products[i].product_id), - GNUNET_JSON_pack_string ("unit_quantity", - unit_quantity_buf)); - } - GNUNET_assert (NULL != ip); - GNUNET_assert (0 == - json_array_append_new (ipa, - ip)); - } - GNUNET_assert (0 == - json_object_set_new (req, - "inventory_products", - ipa)); - } - if (0 != ppoh->num_lock_uuids) - { - json_t *ua = json_array (); - - GNUNET_assert (NULL != ua); - for (unsigned int i = 0; i < ppoh->num_lock_uuids; i++) - { - GNUNET_assert (0 == - json_array_append_new (ua, - json_string ( - ppoh->lock_uuids[i]))); - } - GNUNET_assert (0 == - json_object_set_new (req, - "lock_uuids", - ua)); - } - if (ppoh->create_token_set && - ! ppoh->create_token) - { - GNUNET_assert (0 == - json_object_set_new (req, - "create_token", - json_boolean (ppoh->create_token))); - } - eh = TALER_MERCHANT_curl_easy_get_ (ppoh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppoh->post_ctx, - eh, - req)) ) - { - GNUNET_break (0); - json_decref (req); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req); - ppoh->job = GNUNET_CURL_job_add2 (ppoh->ctx, - eh, - ppoh->post_ctx.headers, - &handle_post_orders_finished, - ppoh); - if (NULL == ppoh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_orders_cancel ( - struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh) -{ - if (NULL != ppoh->job) - { - GNUNET_CURL_job_cancel (ppoh->job); - ppoh->job = NULL; - } - TALER_curl_easy_post_finished (&ppoh->post_ctx); - json_decref (ppoh->order); - GNUNET_free (ppoh->url); - GNUNET_free (ppoh->base_url); - GNUNET_free (ppoh); -} - - -/* end of merchant_api_post-private-orders-new.c */ diff --git a/src/lib/merchant_api_post-private-orders.c b/src/lib/merchant_api_post-private-orders.c @@ -1,26 +1,23 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with TALER; see the file COPYING.LGPL. If not, - see <http://www.gnu.org/licenses/> + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING.LGPL. If not, see + <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-orders.c - * @brief Implementation of the POST /orders + * @file merchant_api_post-private-orders-new.c + * @brief Implementation of the POST /private/orders request * @author Christian Grothoff - * @author Marcello Stanisci */ #include "taler/platform.h" #include <curl/curl.h> @@ -28,22 +25,25 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-private-orders.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> /** - * @brief A POST /orders Handle + * Handle for a POST /private/orders operation. */ -struct TALER_MERCHANT_PostOrdersHandle +struct TALER_MERCHANT_PostPrivateOrdersHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -55,12 +55,12 @@ struct TALER_MERCHANT_PostOrdersHandle /** * Function to call with the result. */ - TALER_MERCHANT_PostOrdersCallback cb; + TALER_MERCHANT_PostPrivateOrdersCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -71,156 +71,365 @@ struct TALER_MERCHANT_PostOrdersHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Order contract terms (JSON). + */ + json_t *order; + + /** + * Optional refund delay. + */ + struct GNUNET_TIME_Relative refund_delay; + + /** + * Whether refund_delay was set. + */ + bool refund_delay_set; + + /** + * Optional payment target. + */ + const char *payment_target; + + /** + * Optional session ID. + */ + const char *session_id; + + /** + * Whether to create a claim token (default: true). + */ + bool create_token; + + /** + * Whether create_token was explicitly set. + */ + bool create_token_set; + + /** + * Optional OTP device ID. + */ + const char *otp_id; + + /** + * Optional inventory products. + */ + const struct TALER_MERCHANT_PostPrivateOrdersInventoryProduct * + inventory_products; + + /** + * Number of inventory products. + */ + unsigned int num_inventory_products; + + /** + * Optional lock UUIDs. + */ + const char **lock_uuids; + + /** + * Number of lock UUIDs. + */ + unsigned int num_lock_uuids; }; /** * Function called when we're done processing the - * HTTP POST /orders request. + * HTTP POST /private/orders request. * - * @param cls the `struct TALER_MERCHANT_PostOrdersHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateOrdersHandle` * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not JSON + * @param response response body, NULL if not in JSON */ static void -handle_post_order_finished (void *cls, - long response_code, - const void *response) +handle_post_orders_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_PostOrdersHandle *po = cls; + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh = cls; const json_t *json = response; + struct TALER_MERCHANT_PostPrivateOrdersResponse por = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json + }; + struct TALER_ClaimTokenP token; - po->job = NULL; - TALER_MERCHANT_handle_order_creation_response_ (po->cb, - po->cb_cls, - response_code, - json); - TALER_MERCHANT_orders_post_cancel (po); + ppoh->job = NULL; + switch (response_code) + { + case 0: + por.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + case MHD_HTTP_OK: + { + bool no_token; + bool no_pay_deadline; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("order_id", + &por.details.ok.order_id), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("token", + &token), + &no_token), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_timestamp ("pay_deadline", + &por.details.ok.pay_deadline), + &no_pay_deadline), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + por.hr.http_status = 0; + por.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + break; + } + if (! no_token) + por.details.ok.token = &token; + if (no_pay_deadline) + por.details.ok.pay_deadline = GNUNET_TIME_UNIT_ZERO_TS; + break; + } + case MHD_HTTP_BAD_REQUEST: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_UNAUTHORIZED: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_FORBIDDEN: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_NOT_FOUND: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_CONFLICT: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_GONE: + { + bool rq_frac_missing; + bool aq_frac_missing; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ( + "product_id", + &por.details.gone.product_id), + GNUNET_JSON_spec_uint64 ( + "requested_quantity", + &por.details.gone.requested_quantity), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint32 ( + "requested_quantity_frac", + &por.details.gone.requested_quantity_frac), + &rq_frac_missing), + GNUNET_JSON_spec_uint64 ( + "available_quantity", + &por.details.gone.available_quantity), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint32 ( + "available_quantity_frac", + &por.details.gone.available_quantity_frac), + &aq_frac_missing), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_timestamp ( + "restock_expected", + &por.details.gone.restock_expected), + NULL), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + por.hr.http_status = 0; + por.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + } + else + { + if (rq_frac_missing) + por.details.gone.requested_quantity_frac = 0; + if (aq_frac_missing) + por.details.gone.available_quantity_frac = 0; + } + break; + } + case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_INTERNAL_SERVER_ERROR: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + break; + default: + por.hr.ec = TALER_JSON_get_error_code (json); + por.hr.hint = TALER_JSON_get_error_hint (json); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d\n", + (unsigned int) response_code, + (int) por.hr.ec); + GNUNET_break_op (0); + break; + } + ppoh->cb (ppoh->cb_cls, + &por); + TALER_MERCHANT_post_private_orders_cancel (ppoh); } -struct TALER_MERCHANT_PostOrdersHandle * -TALER_MERCHANT_orders_post (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const json_t *order, - struct GNUNET_TIME_Relative refund_delay, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls) +struct TALER_MERCHANT_PostPrivateOrdersHandle * +TALER_MERCHANT_post_private_orders_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const json_t *order) { - static const char *no_uuids[GNUNET_NZL (0)]; - - return TALER_MERCHANT_orders_post2 (ctx, - backend_url, - order, - refund_delay, - NULL, - 0, - NULL, - 0, - no_uuids, - true, - cb, - cb_cls); + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh; + + ppoh = GNUNET_new (struct TALER_MERCHANT_PostPrivateOrdersHandle); + ppoh->ctx = ctx; + ppoh->base_url = GNUNET_strdup (url); + ppoh->order = json_incref ((json_t *) order); + return ppoh; } -struct TALER_MERCHANT_PostOrdersHandle * -TALER_MERCHANT_orders_post2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const json_t *order, - struct GNUNET_TIME_Relative refund_delay, - const char *payment_target, - unsigned int inventory_products_length, - const struct TALER_MERCHANT_InventoryProduct inventory_products[], - unsigned int uuids_length, - const char *uuids[], - bool create_token, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls) +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_orders_set_options_ ( + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateOrdersOptionValue *options) { - return TALER_MERCHANT_orders_post3 ( - ctx, - backend_url, - order, - NULL, /* session ID */ - refund_delay, - payment_target, - inventory_products_length, - inventory_products, - uuids_length, - uuids, - create_token, - cb, - cb_cls); + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_REFUND_DELAY: + ppoh->refund_delay = options[i].details.refund_delay; + ppoh->refund_delay_set = true; + break; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_PAYMENT_TARGET: + ppoh->payment_target = options[i].details.payment_target; + break; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_SESSION_ID: + ppoh->session_id = options[i].details.session_id; + break; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_CREATE_TOKEN: + ppoh->create_token = options[i].details.create_token; + ppoh->create_token_set = true; + break; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_OTP_ID: + ppoh->otp_id = options[i].details.otp_id; + break; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_INVENTORY_PRODUCTS: + ppoh->num_inventory_products + = options[i].details.inventory_products.num; + ppoh->inventory_products + = options[i].details.inventory_products.products; + break; + case TALER_MERCHANT_POST_PRIVATE_ORDERS_OPTION_LOCK_UUIDS: + ppoh->num_lock_uuids = options[i].details.lock_uuids.num; + ppoh->lock_uuids = options[i].details.lock_uuids.uuids; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; } -struct TALER_MERCHANT_PostOrdersHandle * -TALER_MERCHANT_orders_post3 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const json_t *order, - const char *session_id, - struct GNUNET_TIME_Relative refund_delay, - const char *payment_target, - unsigned int inventory_products_length, - const struct TALER_MERCHANT_InventoryProduct inventory_products[], - unsigned int uuids_length, - const char *uuids[], - bool create_token, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_post_private_orders_start ( + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh, + TALER_MERCHANT_PostPrivateOrdersCallback cb, + TALER_MERCHANT_POST_PRIVATE_ORDERS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_PostOrdersHandle *po; json_t *req; CURL *eh; - po = GNUNET_new (struct TALER_MERCHANT_PostOrdersHandle); - po->ctx = ctx; - po->cb = cb; - po->cb_cls = cb_cls; - po->url = TALER_url_join (backend_url, - "private/orders", - NULL); + ppoh->cb = cb; + ppoh->cb_cls = cb_cls; + ppoh->url = TALER_url_join (ppoh->base_url, + "private/orders", + NULL); + if (NULL == ppoh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req = GNUNET_JSON_PACK ( GNUNET_JSON_pack_object_incref ("order", - (json_t *) order), + ppoh->order), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("session_id", - session_id)), + ppoh->session_id)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("payment_target", - payment_target))); - if (0 != refund_delay.rel_value_us) + ppoh->payment_target)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("otp_id", + ppoh->otp_id))); + if (ppoh->refund_delay_set && + (0 != ppoh->refund_delay.rel_value_us)) { GNUNET_assert (0 == json_object_set_new (req, "refund_delay", GNUNET_JSON_from_time_rel ( - refund_delay))); + ppoh->refund_delay))); } - if (0 != inventory_products_length) + if (0 != ppoh->num_inventory_products) { json_t *ipa = json_array (); GNUNET_assert (NULL != ipa); - for (unsigned int i = 0; i<inventory_products_length; i++) + for (unsigned int i = 0; i < ppoh->num_inventory_products; i++) { json_t *ip; - char unit_quantity_buf[64]; - - TALER_MERCHANT_format_quantity_string (inventory_products[i].quantity, - inventory_products[i].quantity_frac - , - unit_quantity_buf, - sizeof (unit_quantity_buf)); - - ip = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("product_id", - inventory_products[i].product_id), - GNUNET_JSON_pack_string ("unit_quantity", - unit_quantity_buf)); + + if (ppoh->inventory_products[i].use_fractional_quantity) + { + char unit_quantity_buf[64]; + + TALER_MERCHANT_format_quantity_string ( + ppoh->inventory_products[i].quantity, + ppoh->inventory_products[i].quantity_frac, + unit_quantity_buf, + sizeof (unit_quantity_buf)); + ip = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("product_id", + ppoh->inventory_products[i].product_id), + GNUNET_JSON_pack_string ("unit_quantity", + unit_quantity_buf)); + } + else + { + char unit_quantity_buf[64]; + + TALER_MERCHANT_format_quantity_string ( + ppoh->inventory_products[i].quantity, + 0, + unit_quantity_buf, + sizeof (unit_quantity_buf)); + ip = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("product_id", + ppoh->inventory_products[i].product_id), + GNUNET_JSON_pack_string ("unit_quantity", + unit_quantity_buf)); + } GNUNET_assert (NULL != ip); GNUNET_assert (0 == json_array_append_new (ipa, @@ -231,67 +440,71 @@ TALER_MERCHANT_orders_post3 ( "inventory_products", ipa)); } - if (0 != uuids_length) + if (0 != ppoh->num_lock_uuids) { json_t *ua = json_array (); GNUNET_assert (NULL != ua); - for (unsigned int i = 0; i<uuids_length; i++) + for (unsigned int i = 0; i < ppoh->num_lock_uuids; i++) { - json_t *u; - - u = json_string (uuids[i]); GNUNET_assert (0 == json_array_append_new (ua, - u)); + json_string ( + ppoh->lock_uuids[i]))); } GNUNET_assert (0 == json_object_set_new (req, "lock_uuids", ua)); } - if (! create_token) + if (ppoh->create_token_set && + ! ppoh->create_token) { GNUNET_assert (0 == json_object_set_new (req, "create_token", - json_boolean (create_token))); + json_boolean (ppoh->create_token))); } - eh = TALER_MERCHANT_curl_easy_get_ (po->url); - if (GNUNET_OK != - TALER_curl_easy_post (&po->post_ctx, - eh, - req)) + eh = TALER_MERCHANT_curl_easy_get_ (ppoh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppoh->post_ctx, + eh, + req)) ) { GNUNET_break (0); - curl_easy_cleanup (eh); json_decref (req); - GNUNET_free (po); - return NULL; + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } json_decref (req); - po->job = GNUNET_CURL_job_add2 (ctx, - eh, - po->post_ctx.headers, - &handle_post_order_finished, - po); - return po; + ppoh->job = GNUNET_CURL_job_add2 (ppoh->ctx, + eh, + ppoh->post_ctx.headers, + &handle_post_orders_finished, + ppoh); + if (NULL == ppoh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_orders_post_cancel ( - struct TALER_MERCHANT_PostOrdersHandle *po) +TALER_MERCHANT_post_private_orders_cancel ( + struct TALER_MERCHANT_PostPrivateOrdersHandle *ppoh) { - if (NULL != po->job) + if (NULL != ppoh->job) { - GNUNET_CURL_job_cancel (po->job); - po->job = NULL; + GNUNET_CURL_job_cancel (ppoh->job); + ppoh->job = NULL; } - GNUNET_free (po->url); - TALER_curl_easy_post_finished (&po->post_ctx); - GNUNET_free (po); + TALER_curl_easy_post_finished (&ppoh->post_ctx); + json_decref (ppoh->order); + GNUNET_free (ppoh->url); + GNUNET_free (ppoh->base_url); + GNUNET_free (ppoh); } -/* end of merchant_api_post_orders.c */ +/* end of merchant_api_post-private-orders-new.c */ diff --git a/src/lib/merchant_api_post-private-otp-devices-new.c b/src/lib/merchant_api_post-private-otp-devices-new.c @@ -1,273 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-otp-devices-new.c - * @brief Implementation of the POST /private/otp-devices request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-otp-devices-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/otp-devices operation. - */ -struct TALER_MERCHANT_PostPrivateOtpDevicesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateOtpDevicesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * OTP device identifier. - */ - char *otp_device_id; - - /** - * Human-readable description. - */ - char *otp_device_description; - - /** - * Base32-encoded OTP secret key (or NULL). - */ - char *otp_key; - - /** - * OTP algorithm to use. - */ - enum TALER_MerchantConfirmationAlgorithm otp_algorithm; - - /** - * Initial counter value (for HOTP). - */ - uint64_t otp_ctr; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/otp-devices request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateOtpDevicesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_otp_devices_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateOtpDevicesResponse odr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppoh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/otp-devices completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - odr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - odr.hr.ec = TALER_JSON_get_error_code (json); - odr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &odr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) odr.hr.ec); - GNUNET_break_op (0); - break; - } - ppoh->cb (ppoh->cb_cls, - &odr); - TALER_MERCHANT_post_private_otp_devices_cancel (ppoh); -} - - -struct TALER_MERCHANT_PostPrivateOtpDevicesHandle * -TALER_MERCHANT_post_private_otp_devices_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *otp_device_id, - const char *otp_device_description, - const char *otp_key, - enum TALER_MerchantConfirmationAlgorithm otp_algorithm, - uint64_t otp_ctr) -{ - struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh; - - ppoh = GNUNET_new (struct TALER_MERCHANT_PostPrivateOtpDevicesHandle); - ppoh->ctx = ctx; - ppoh->base_url = GNUNET_strdup (url); - ppoh->otp_device_id = GNUNET_strdup (otp_device_id); - ppoh->otp_device_description = GNUNET_strdup (otp_device_description); - if (NULL != otp_key) - ppoh->otp_key = GNUNET_strdup (otp_key); - ppoh->otp_algorithm = otp_algorithm; - ppoh->otp_ctr = otp_ctr; - return ppoh; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_otp_devices_start ( - struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, - TALER_MERCHANT_PostPrivateOtpDevicesCallback cb, - TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppoh->cb = cb; - ppoh->cb_cls = cb_cls; - ppoh->url = TALER_url_join (ppoh->base_url, - "private/otp-devices", - NULL); - if (NULL == ppoh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("otp_device_id", - ppoh->otp_device_id), - GNUNET_JSON_pack_string ("otp_device_description", - ppoh->otp_device_description), - GNUNET_JSON_pack_uint64 ("otp_algorithm", - (uint32_t) ppoh->otp_algorithm), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("otp_key", - ppoh->otp_key)), - GNUNET_JSON_pack_uint64 ("otp_ctr", - ppoh->otp_ctr)); - eh = TALER_MERCHANT_curl_easy_get_ (ppoh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppoh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppoh->job = GNUNET_CURL_job_add2 (ppoh->ctx, - eh, - ppoh->post_ctx.headers, - &handle_post_otp_devices_finished, - ppoh); - if (NULL == ppoh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_otp_devices_cancel ( - struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh) -{ - if (NULL != ppoh->job) - { - GNUNET_CURL_job_cancel (ppoh->job); - ppoh->job = NULL; - } - TALER_curl_easy_post_finished (&ppoh->post_ctx); - GNUNET_free (ppoh->otp_device_id); - GNUNET_free (ppoh->otp_device_description); - GNUNET_free (ppoh->otp_key); - GNUNET_free (ppoh->url); - GNUNET_free (ppoh->base_url); - GNUNET_free (ppoh); -} - - -/* end of merchant_api_post-private-otp-devices-new.c */ diff --git a/src/lib/merchant_api_post-private-otp-devices.c b/src/lib/merchant_api_post-private-otp-devices.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-otp-devices.c - * @brief Implementation of the POST /otp-devices request - * of the merchant's HTTP API + * @file merchant_api_post-private-otp-devices-new.c + * @brief Implementation of the POST /private/otp-devices request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,7 +26,8 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-otp-devices.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -35,13 +35,17 @@ /** - * Handle for a POST /otp-devices/$ID operation. + * Handle for a POST /private/otp-devices operation. */ -struct TALER_MERCHANT_OtpDevicesPostHandle +struct TALER_MERCHANT_PostPrivateOtpDevicesHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_OtpDevicesPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_OtpDevicesPostCallback cb; + TALER_MERCHANT_PostPrivateOtpDevicesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -69,14 +73,39 @@ struct TALER_MERCHANT_OtpDevicesPostHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * OTP device identifier. + */ + char *otp_device_id; + + /** + * Human-readable description. + */ + char *otp_device_description; + + /** + * Base32-encoded OTP secret key (or NULL). + */ + char *otp_key; + + /** + * OTP algorithm to use. + */ + enum TALER_MerchantConfirmationAlgorithm otp_algorithm; + + /** + * Initial counter value (for HOTP). + */ + uint64_t otp_ctr; }; /** * Function called when we're done processing the - * HTTP POST /otp-devices request. + * HTTP POST /private/otp-devices request. * - * @param cls the `struct TALER_MERCHANT_OtpDevicesPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateOtpDevicesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -85,153 +114,160 @@ handle_post_otp_devices_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_OtpDevicesPostHandle *tph = cls; + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateOtpDevicesResponse odr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tph->job = NULL; + ppoh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /otp-devices completed with response code %u\n", + "POST /private/otp-devices completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + odr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + odr.hr.ec = TALER_JSON_get_error_code (json); + odr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &odr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) odr.hr.ec); GNUNET_break_op (0); break; } - tph->cb (tph->cb_cls, - &hr); - TALER_MERCHANT_otp_devices_post_cancel (tph); + ppoh->cb (ppoh->cb_cls, + &odr); + TALER_MERCHANT_post_private_otp_devices_cancel (ppoh); } -struct TALER_MERCHANT_OtpDevicesPostHandle * -TALER_MERCHANT_otp_devices_post ( +struct TALER_MERCHANT_PostPrivateOtpDevicesHandle * +TALER_MERCHANT_post_private_otp_devices_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *otp_device_id, const char *otp_device_description, const char *otp_key, enum TALER_MerchantConfirmationAlgorithm otp_algorithm, - uint64_t otp_ctr, - TALER_MERCHANT_OtpDevicesPostCallback cb, - void *cb_cls) + uint64_t otp_ctr) +{ + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh; + + ppoh = GNUNET_new (struct TALER_MERCHANT_PostPrivateOtpDevicesHandle); + ppoh->ctx = ctx; + ppoh->base_url = GNUNET_strdup (url); + ppoh->otp_device_id = GNUNET_strdup (otp_device_id); + ppoh->otp_device_description = GNUNET_strdup (otp_device_description); + if (NULL != otp_key) + ppoh->otp_key = GNUNET_strdup (otp_key); + ppoh->otp_algorithm = otp_algorithm; + ppoh->otp_ctr = otp_ctr; + return ppoh; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_otp_devices_start ( + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh, + TALER_MERCHANT_PostPrivateOtpDevicesCallback cb, + TALER_MERCHANT_POST_PRIVATE_OTP_DEVICES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_OtpDevicesPostHandle *tph; json_t *req_obj; + CURL *eh; + ppoh->cb = cb; + ppoh->cb_cls = cb_cls; + ppoh->url = TALER_url_join (ppoh->base_url, + "private/otp-devices", + NULL); + if (NULL == ppoh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("otp_device_id", - otp_device_id), + ppoh->otp_device_id), GNUNET_JSON_pack_string ("otp_device_description", - otp_device_description), + ppoh->otp_device_description), GNUNET_JSON_pack_uint64 ("otp_algorithm", - (uint32_t) otp_algorithm), + (uint32_t) ppoh->otp_algorithm), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("otp_key", - otp_key)), + ppoh->otp_key)), GNUNET_JSON_pack_uint64 ("otp_ctr", - otp_ctr)); - tph = GNUNET_new (struct TALER_MERCHANT_OtpDevicesPostHandle); - tph->ctx = ctx; - tph->cb = cb; - tph->cb_cls = cb_cls; - tph->url = TALER_url_join (backend_url, - "private/otp-devices", - NULL); - if (NULL == tph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } + ppoh->otp_ctr)); + eh = TALER_MERCHANT_curl_easy_get_ (ppoh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppoh->post_ctx, + eh, + req_obj)) ) { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tph->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&tph->post_ctx, - eh, - req_obj)); + GNUNET_break (0); json_decref (req_obj); - tph->job = GNUNET_CURL_job_add2 (ctx, - eh, - tph->post_ctx.headers, - &handle_post_otp_devices_finished, - tph); - GNUNET_assert (NULL != tph->job); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return tph; + json_decref (req_obj); + ppoh->job = GNUNET_CURL_job_add2 (ppoh->ctx, + eh, + ppoh->post_ctx.headers, + &handle_post_otp_devices_finished, + ppoh); + if (NULL == ppoh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_otp_devices_post_cancel ( - struct TALER_MERCHANT_OtpDevicesPostHandle *tph) +TALER_MERCHANT_post_private_otp_devices_cancel ( + struct TALER_MERCHANT_PostPrivateOtpDevicesHandle *ppoh) { - if (NULL != tph->job) + if (NULL != ppoh->job) { - GNUNET_CURL_job_cancel (tph->job); - tph->job = NULL; + GNUNET_CURL_job_cancel (ppoh->job); + ppoh->job = NULL; } - TALER_curl_easy_post_finished (&tph->post_ctx); - GNUNET_free (tph->url); - GNUNET_free (tph); + TALER_curl_easy_post_finished (&ppoh->post_ctx); + GNUNET_free (ppoh->otp_device_id); + GNUNET_free (ppoh->otp_device_description); + GNUNET_free (ppoh->otp_key); + GNUNET_free (ppoh->url); + GNUNET_free (ppoh->base_url); + GNUNET_free (ppoh); } -/* end of merchant_api_post_otp_devices.c */ +/* end of merchant_api_post-private-otp-devices-new.c */ diff --git a/src/lib/merchant_api_post-private-products-PRODUCT_ID-lock-new.c b/src/lib/merchant_api_post-private-products-PRODUCT_ID-lock-new.c @@ -1,314 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-products-PRODUCT_ID-lock-new.c - * @brief Implementation of the POST /private/products/$PRODUCT_ID/lock request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/products/$PRODUCT_ID/lock operation. - */ -struct TALER_MERCHANT_PostPrivateProductsLockHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateProductsLockCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Product identifier. - */ - char *product_id; - - /** - * Lock UUID. - */ - char *uuid; - - /** - * How long to lock the inventory. - */ - struct GNUNET_TIME_Relative duration; - - /** - * Number of units to lock. - */ - uint64_t quantity; - - /** - * Fractional part of the quantity. - */ - uint32_t quantity_frac; - - /** - * Whether to use fractional quantity. - */ - bool use_fractional_quantity; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/products/$PRODUCT_ID/lock request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateProductsLockHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_products_lock_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateProductsLockResponse plr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - pplh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/products/$PRODUCT_ID/lock completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - plr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - plr.hr.ec = TALER_JSON_get_error_code (json); - plr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_BAD_REQUEST: - GNUNET_break_op (0); - plr.hr.ec = TALER_JSON_get_error_code (json); - plr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - plr.hr.ec = TALER_JSON_get_error_code (json); - plr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - plr.hr.ec = TALER_JSON_get_error_code (json); - plr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_GONE: - plr.hr.ec = TALER_JSON_get_error_code (json); - plr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - plr.hr.ec = TALER_JSON_get_error_code (json); - plr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &plr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) plr.hr.ec); - GNUNET_break_op (0); - break; - } - pplh->cb (pplh->cb_cls, - &plr); - TALER_MERCHANT_post_private_products_lock_cancel (pplh); -} - - -struct TALER_MERCHANT_PostPrivateProductsLockHandle * -TALER_MERCHANT_post_private_products_lock_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id, - const char *uuid, - struct GNUNET_TIME_Relative duration, - uint64_t quantity) -{ - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh; - - pplh = GNUNET_new (struct TALER_MERCHANT_PostPrivateProductsLockHandle); - pplh->ctx = ctx; - pplh->base_url = GNUNET_strdup (url); - pplh->product_id = GNUNET_strdup (product_id); - pplh->uuid = GNUNET_strdup (uuid); - pplh->duration = duration; - pplh->quantity = quantity; - return pplh; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_products_lock_set_options_ ( - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC: - pplh->quantity_frac = options[i].details.quantity_frac; - break; - case - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY: - pplh->use_fractional_quantity - = options[i].details.use_fractional_quantity; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_products_lock_start ( - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, - TALER_MERCHANT_PostPrivateProductsLockCallback cb, - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - char unit_quantity_buf[64]; - - pplh->cb = cb; - pplh->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "private/products/%s/lock", - pplh->product_id); - pplh->url = TALER_url_join (pplh->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == pplh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - GNUNET_assert ( (0 == pplh->quantity_frac) || - pplh->use_fractional_quantity); - TALER_MERCHANT_format_quantity_string (pplh->quantity, - pplh->quantity_frac, - unit_quantity_buf, - sizeof (unit_quantity_buf)); - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("lock_uuid", - pplh->uuid), - GNUNET_JSON_pack_time_rel ("duration", - pplh->duration), - GNUNET_JSON_pack_string ("unit_quantity", - unit_quantity_buf)); - eh = TALER_MERCHANT_curl_easy_get_ (pplh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pplh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - pplh->job = GNUNET_CURL_job_add2 (pplh->ctx, - eh, - pplh->post_ctx.headers, - &handle_post_products_lock_finished, - pplh); - if (NULL == pplh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_products_lock_cancel ( - struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh) -{ - if (NULL != pplh->job) - { - GNUNET_CURL_job_cancel (pplh->job); - pplh->job = NULL; - } - TALER_curl_easy_post_finished (&pplh->post_ctx); - GNUNET_free (pplh->product_id); - GNUNET_free (pplh->uuid); - GNUNET_free (pplh->url); - GNUNET_free (pplh->base_url); - GNUNET_free (pplh); -} - - -/* end of merchant_api_post-private-products-PRODUCT_ID-lock-new.c */ diff --git a/src/lib/merchant_api_post-private-products-PRODUCT_ID-lock.c b/src/lib/merchant_api_post-private-products-PRODUCT_ID-lock.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-products-PRODUCT_ID-lock.c - * @brief Implementation of the POST /products/$ID/lock request - * of the merchant's HTTP API + * @file merchant_api_post-private-products-PRODUCT_ID-lock-new.c + * @brief Implementation of the POST /private/products/$PRODUCT_ID/lock request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,21 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a POST /products/$ID/lock operation. + * Handle for a POST /private/products/$PRODUCT_ID/lock operation. */ -struct TALER_MERCHANT_ProductLockHandle +struct TALER_MERCHANT_PostPrivateProductsLockHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_ProductLockHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductLockCallback cb; + TALER_MERCHANT_PostPrivateProductsLockCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,210 +74,241 @@ struct TALER_MERCHANT_ProductLockHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Product identifier. + */ + char *product_id; + + /** + * Lock UUID. + */ + char *uuid; + + /** + * How long to lock the inventory. + */ + struct GNUNET_TIME_Relative duration; + + /** + * Number of units to lock. + */ + uint64_t quantity; + + /** + * Fractional part of the quantity. + */ + uint32_t quantity_frac; + + /** + * Whether to use fractional quantity. + */ + bool use_fractional_quantity; }; /** * Function called when we're done processing the - * HTTP POST /products/$ID/lock request. + * HTTP POST /private/products/$PRODUCT_ID/lock request. * - * @param cls the `struct TALER_MERCHANT_ProductLockHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateProductsLockHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_lock_product_finished (void *cls, - long response_code, - const void *response) +handle_post_products_lock_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_ProductLockHandle *plh = cls; + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateProductsLockResponse plr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - plh->job = NULL; + pplh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "LOCK /products/$ID completed with response code %u\n", + "POST /private/products/$PRODUCT_ID/lock completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + plr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + plr.hr.ec = TALER_JSON_get_error_code (json); + plr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); GNUNET_break_op (0); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + plr.hr.ec = TALER_JSON_get_error_code (json); + plr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + plr.hr.ec = TALER_JSON_get_error_code (json); + plr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + plr.hr.ec = TALER_JSON_get_error_code (json); + plr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_GONE: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + plr.hr.ec = TALER_JSON_get_error_code (json); + plr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + plr.hr.ec = TALER_JSON_get_error_code (json); + plr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &plr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) plr.hr.ec); GNUNET_break_op (0); break; } - plh->cb (plh->cb_cls, - &hr); - TALER_MERCHANT_product_lock_cancel (plh); + pplh->cb (pplh->cb_cls, + &plr); + TALER_MERCHANT_post_private_products_lock_cancel (pplh); } -struct TALER_MERCHANT_ProductLockHandle * -TALER_MERCHANT_product_lock2 ( +struct TALER_MERCHANT_PostPrivateProductsLockHandle * +TALER_MERCHANT_post_private_products_lock_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *product_id, const char *uuid, struct GNUNET_TIME_Relative duration, - uint64_t quantity, - uint32_t quantity_frac, - bool use_fractional_quantity, - TALER_MERCHANT_ProductLockCallback cb, - void *cb_cls) + uint64_t quantity) +{ + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh; + + pplh = GNUNET_new (struct TALER_MERCHANT_PostPrivateProductsLockHandle); + pplh->ctx = ctx; + pplh->base_url = GNUNET_strdup (url); + pplh->product_id = GNUNET_strdup (product_id); + pplh->uuid = GNUNET_strdup (uuid); + pplh->duration = duration; + pplh->quantity = quantity; + return pplh; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_products_lock_set_options_ ( + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateProductsLockOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_QUANTITY_FRAC: + pplh->quantity_frac = options[i].details.quantity_frac; + break; + case + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_OPTION_USE_FRACTIONAL_QUANTITY: + pplh->use_fractional_quantity + = options[i].details.use_fractional_quantity; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_products_lock_start ( + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh, + TALER_MERCHANT_PostPrivateProductsLockCallback cb, + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_LOCK_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ProductLockHandle *plh; json_t *req_obj; + CURL *eh; char unit_quantity_buf[64]; - TALER_MERCHANT_format_quantity_string (quantity, - quantity_frac, - unit_quantity_buf, - sizeof (unit_quantity_buf)); - - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("lock_uuid", - uuid), - GNUNET_JSON_pack_time_rel ("duration", - duration), - GNUNET_JSON_pack_string ("unit_quantity", - unit_quantity_buf)); - (void) use_fractional_quantity; - GNUNET_assert ( (0 == quantity_frac) || use_fractional_quantity); - plh = GNUNET_new (struct TALER_MERCHANT_ProductLockHandle); - plh->ctx = ctx; - plh->cb = cb; - plh->cb_cls = cb_cls; + pplh->cb = cb; + pplh->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "private/products/%s/lock", - product_id); - plh->url = TALER_url_join (backend_url, - path, - NULL); + pplh->product_id); + pplh->url = TALER_url_join (pplh->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == plh->url) + if (NULL == pplh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + GNUNET_assert ( (0 == pplh->quantity_frac) || + pplh->use_fractional_quantity); + TALER_MERCHANT_format_quantity_string (pplh->quantity, + pplh->quantity_frac, + unit_quantity_buf, + sizeof (unit_quantity_buf)); + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("lock_uuid", + pplh->uuid), + GNUNET_JSON_pack_time_rel ("duration", + pplh->duration), + GNUNET_JSON_pack_string ("unit_quantity", + unit_quantity_buf)); + eh = TALER_MERCHANT_curl_easy_get_ (pplh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pplh->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (plh); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (plh->url); - if (GNUNET_OK != - TALER_curl_easy_post (&plh->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (plh->url); - GNUNET_free (plh); - return NULL; - } - json_decref (req_obj); - plh->job = GNUNET_CURL_job_add2 (ctx, - eh, - plh->post_ctx.headers, - &handle_lock_product_finished, - plh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return plh; + json_decref (req_obj); + pplh->job = GNUNET_CURL_job_add2 (pplh->ctx, + eh, + pplh->post_ctx.headers, + &handle_post_products_lock_finished, + pplh); + if (NULL == pplh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_product_lock_cancel ( - struct TALER_MERCHANT_ProductLockHandle *plh) +TALER_MERCHANT_post_private_products_lock_cancel ( + struct TALER_MERCHANT_PostPrivateProductsLockHandle *pplh) { - if (NULL != plh->job) + if (NULL != pplh->job) { - GNUNET_CURL_job_cancel (plh->job); - plh->job = NULL; + GNUNET_CURL_job_cancel (pplh->job); + pplh->job = NULL; } - TALER_curl_easy_post_finished (&plh->post_ctx); - GNUNET_free (plh->url); - GNUNET_free (plh); -} - - -struct TALER_MERCHANT_ProductLockHandle * -TALER_MERCHANT_product_lock ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *product_id, - const char *uuid, - struct GNUNET_TIME_Relative duration, - uint32_t quantity, - TALER_MERCHANT_ProductLockCallback cb, - void *cb_cls) -{ - return TALER_MERCHANT_product_lock2 (ctx, - backend_url, - product_id, - uuid, - duration, - quantity, - 0, - false, - cb, - cb_cls); + TALER_curl_easy_post_finished (&pplh->post_ctx); + GNUNET_free (pplh->product_id); + GNUNET_free (pplh->uuid); + GNUNET_free (pplh->url); + GNUNET_free (pplh->base_url); + GNUNET_free (pplh); } -/* end of merchant_api_lock_product.c */ +/* end of merchant_api_post-private-products-PRODUCT_ID-lock-new.c */ diff --git a/src/lib/merchant_api_post-private-products-new.c b/src/lib/merchant_api_post-private-products-new.c @@ -1,498 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-products-new.c - * @brief Implementation of the POST /private/products request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-products-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/products operation. - */ -struct TALER_MERCHANT_PostPrivateProductsHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateProductsCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Product identifier. - */ - char *product_id; - - /** - * Human-readable description. - */ - char *description; - - /** - * Unit of measurement. - */ - char *unit; - - /** - * Unit price. - */ - struct TALER_Amount price; - - /** - * Product image (base64-encoded or empty). - */ - char *image; - - /** - * Total stock (-1 for unlimited). - */ - int64_t total_stock; - - /** - * Optional internationalized descriptions (JSON). - */ - const json_t *description_i18n; - - /** - * Optional tax information (JSON array). - */ - const json_t *taxes; - - /** - * Optional storage location (JSON). - */ - const json_t *address; - - /** - * Optional expected restock time. - */ - struct GNUNET_TIME_Timestamp next_restock; - - /** - * Whether next_restock has been set. - */ - bool have_next_restock; - - /** - * Optional minimum age requirement. - */ - uint32_t minimum_age; - - /** - * Whether minimum_age has been set. - */ - bool have_minimum_age; - - /** - * Optional category IDs. - */ - const uint64_t *cats; - - /** - * Number of category IDs. - */ - unsigned int num_cats; - - /** - * Optional additional unit prices. - */ - const struct TALER_Amount *unit_prices; - - /** - * Number of additional unit prices. - */ - size_t unit_prices_len; - - /** - * Fractional part of total stock. - */ - uint32_t total_stock_frac; - - /** - * Whether fractional quantities are allowed. - */ - bool unit_allow_fraction; - - /** - * Whether unit_allow_fraction has been set. - */ - bool have_unit_allow_fraction; - - /** - * Precision level for fractions. - */ - uint32_t unit_precision_level; - - /** - * Whether unit_precision_level has been set. - */ - bool have_unit_precision_level; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/products request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateProductsHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_products_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateProductsResponse ppr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppph->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/products completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - ppr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - ppr.hr.ec = TALER_JSON_get_error_code (json); - ppr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &ppr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ppr.hr.ec); - GNUNET_break_op (0); - break; - } - ppph->cb (ppph->cb_cls, - &ppr); - TALER_MERCHANT_post_private_products_cancel (ppph); -} - - -struct TALER_MERCHANT_PostPrivateProductsHandle * -TALER_MERCHANT_post_private_products_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *product_id, - const char *description, - const char *unit, - const struct TALER_Amount *price, - const char *image, - int64_t total_stock) -{ - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph; - - ppph = GNUNET_new (struct TALER_MERCHANT_PostPrivateProductsHandle); - ppph->ctx = ctx; - ppph->base_url = GNUNET_strdup (url); - 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; - return ppph; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_products_set_options_ ( - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateProductsOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - 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; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES: - ppph->taxes = options[i].details.taxes; - break; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS: - ppph->address = options[i].details.address; - break; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK: - ppph->next_restock = options[i].details.next_restock; - ppph->have_next_restock = true; - break; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE: - ppph->minimum_age = options[i].details.minimum_age; - ppph->have_minimum_age = true; - break; - 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; - case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC: - ppph->total_stock_frac = options[i].details.total_stock_frac; - break; - 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; - 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; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_products_start ( - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, - TALER_MERCHANT_PostPrivateProductsCallback cb, - TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls) -{ - 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; - ppph->cb_cls = cb_cls; - ppph->url = TALER_url_join (ppph->base_url, - "private/products", - NULL); - if (NULL == ppph->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - - TALER_MERCHANT_format_stock_string (ppph->total_stock, - ppph->total_stock_frac, - unit_total_stock_buf, - sizeof (unit_total_stock_buf)); - - if (0 == ppph->num_cats) - { - categories = NULL; - } - else - { - categories = json_array (); - GNUNET_assert (NULL != categories); - for (unsigned int i = 0; i < ppph->num_cats; i++) - GNUNET_assert (0 == - json_array_append_new (categories, - 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), - GNUNET_JSON_pack_string ("description", - ppph->description), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) 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), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_incref ("taxes", - (json_t *) 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)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_timestamp ("next_restock", - ppph->have_next_restock - ? ppph->next_restock - : GNUNET_TIME_UNIT_ZERO_TS))); - if (ppph->have_minimum_age) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "minimum_age", - json_integer ( - ppph->minimum_age))); - } - if (ppph->have_unit_allow_fraction && - ppph->unit_allow_fraction) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_allow_fraction", - json_true ())); - if (ppph->have_unit_precision_level) - { - GNUNET_assert (0 == - json_object_set_new (req_obj, - "unit_precision_level", - json_integer ( - ppph->unit_precision_level))); - } - } - eh = TALER_MERCHANT_curl_easy_get_ (ppph->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppph->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppph->job = GNUNET_CURL_job_add2 (ppph->ctx, - eh, - ppph->post_ctx.headers, - &handle_post_products_finished, - ppph); - if (NULL == ppph->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_products_cancel ( - struct TALER_MERCHANT_PostPrivateProductsHandle *ppph) -{ - if (NULL != ppph->job) - { - GNUNET_CURL_job_cancel (ppph->job); - ppph->job = NULL; - } - TALER_curl_easy_post_finished (&ppph->post_ctx); - GNUNET_free (ppph->product_id); - GNUNET_free (ppph->description); - GNUNET_free (ppph->unit); - GNUNET_free (ppph->image); - GNUNET_free (ppph->url); - GNUNET_free (ppph->base_url); - GNUNET_free (ppph); -} - - -/* end of merchant_api_post-private-products-new.c */ diff --git a/src/lib/merchant_api_post-private-products.c b/src/lib/merchant_api_post-private-products.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2024 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,9 +17,8 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-products.c - * @brief Implementation of the POST /products request - * of the merchant's HTTP API + * @file merchant_api_post-private-products-new.c + * @brief Implementation of the POST /private/products request * @author Christian Grothoff */ #include "taler/platform.h" @@ -27,7 +26,8 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-products.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -35,13 +35,17 @@ /** - * Handle for a POST /products/$ID operation. + * Handle for a POST /private/products operation. */ -struct TALER_MERCHANT_ProductsPostHandle +struct TALER_MERCHANT_PostPrivateProductsHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_ProductsPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_ProductsPostCallback cb; + TALER_MERCHANT_PostPrivateProductsCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,123 @@ struct TALER_MERCHANT_ProductsPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Product identifier. + */ + char *product_id; + + /** + * Human-readable description. + */ + char *description; + + /** + * Unit of measurement. + */ + char *unit; + + /** + * Unit price. + */ + struct TALER_Amount price; + + /** + * Product image (base64-encoded or empty). + */ + char *image; + + /** + * Total stock (-1 for unlimited). + */ + int64_t total_stock; + + /** + * Optional internationalized descriptions (JSON). + */ + const json_t *description_i18n; + + /** + * Optional tax information (JSON array). + */ + const json_t *taxes; + + /** + * Optional storage location (JSON). + */ + const json_t *address; + + /** + * Optional expected restock time. + */ + struct GNUNET_TIME_Timestamp next_restock; + + /** + * Whether next_restock has been set. + */ + bool have_next_restock; + + /** + * Optional minimum age requirement. + */ + uint32_t minimum_age; + + /** + * Whether minimum_age has been set. + */ + bool have_minimum_age; + + /** + * Optional category IDs. + */ + const uint64_t *cats; + + /** + * Number of category IDs. + */ + unsigned int num_cats; + + /** + * Optional additional unit prices. + */ + const struct TALER_Amount *unit_prices; + + /** + * Number of additional unit prices. + */ + size_t unit_prices_len; + + /** + * Fractional part of total stock. + */ + uint32_t total_stock_frac; + + /** + * Whether fractional quantities are allowed. + */ + bool unit_allow_fraction; + + /** + * Whether unit_allow_fraction has been set. + */ + bool have_unit_allow_fraction; + + /** + * Precision level for fractions. + */ + uint32_t unit_precision_level; + + /** + * Whether unit_precision_level has been set. + */ + bool have_unit_precision_level; }; /** * Function called when we're done processing the - * HTTP POST /products request. + * HTTP POST /private/products request. * - * @param cls the `struct TALER_MERCHANT_ProductsPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateProductsHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,113 +199,175 @@ handle_post_products_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_ProductsPostHandle *pph = cls; + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateProductsResponse ppr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - pph->job = NULL; + ppph->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /products completed with response code %u\n", + "POST /private/products completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ppr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + ppr.hr.ec = TALER_JSON_get_error_code (json); + ppr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &ppr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) ppr.hr.ec); GNUNET_break_op (0); break; } - pph->cb (pph->cb_cls, - &hr); - TALER_MERCHANT_products_post_cancel (pph); + ppph->cb (ppph->cb_cls, + &ppr); + TALER_MERCHANT_post_private_products_cancel (ppph); } -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post4 ( +struct TALER_MERCHANT_PostPrivateProductsHandle * +TALER_MERCHANT_post_private_products_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *product_id, const char *description, - const json_t *description_i18n, const char *unit, - const struct TALER_Amount *unit_prices, - size_t unit_price_len, + const struct TALER_Amount *price, const char *image, - const json_t *taxes, - int64_t total_stock, - uint32_t total_stock_frac, - bool unit_allow_fraction, - const uint32_t *unit_precision_level, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - uint32_t minimum_age, - unsigned int num_cats, - const uint64_t *cats, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls) + int64_t total_stock) +{ + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph; + + ppph = GNUNET_new (struct TALER_MERCHANT_PostPrivateProductsHandle); + ppph->ctx = ctx; + ppph->base_url = GNUNET_strdup (url); + 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; + return ppph; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_products_set_options_ ( + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateProductsOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + 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; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TAXES: + ppph->taxes = options[i].details.taxes; + break; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_ADDRESS: + ppph->address = options[i].details.address; + break; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_NEXT_RESTOCK: + ppph->next_restock = options[i].details.next_restock; + ppph->have_next_restock = true; + break; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_MINIMUM_AGE: + ppph->minimum_age = options[i].details.minimum_age; + ppph->have_minimum_age = true; + break; + 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; + case TALER_MERCHANT_POST_PRIVATE_PRODUCTS_OPTION_TOTAL_STOCK_FRAC: + ppph->total_stock_frac = options[i].details.total_stock_frac; + break; + 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; + 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; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_products_start ( + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph, + TALER_MERCHANT_PostPrivateProductsCallback cb, + TALER_MERCHANT_POST_PRIVATE_PRODUCTS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_ProductsPostHandle *pph; 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]; - TALER_MERCHANT_format_stock_string (total_stock, - total_stock_frac, + ppph->cb = cb; + ppph->cb_cls = cb_cls; + ppph->url = TALER_url_join (ppph->base_url, + "private/products", + NULL); + if (NULL == ppph->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + + TALER_MERCHANT_format_stock_string (ppph->total_stock, + ppph->total_stock_frac, unit_total_stock_buf, sizeof (unit_total_stock_buf)); - if (0 == num_cats) + if (0 == ppph->num_cats) { categories = NULL; } @@ -200,234 +375,124 @@ TALER_MERCHANT_products_post4 ( { categories = json_array (); GNUNET_assert (NULL != categories); - for (unsigned int i = 0; i<num_cats; i++) + for (unsigned int i = 0; i < ppph->num_cats; i++) GNUNET_assert (0 == json_array_append_new (categories, - json_integer (cats[i]))); + json_integer (ppph->cats[i]))); } + + if ( (NULL != ppph->unit_prices) && + (0 < ppph->unit_prices_len) ) { - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("product_id", - product_id), - /* FIXME: once we move to the new-style API, - allow applications to set the product name properly! */ - GNUNET_JSON_pack_string ("product_name", - description), - GNUNET_JSON_pack_string ("description", - description), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) description_i18n)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_steal ("categories", - categories)), - GNUNET_JSON_pack_string ("unit", - unit), - TALER_JSON_pack_amount_array ("unit_price", - unit_price_len, - unit_prices), - GNUNET_JSON_pack_string ("image", - image), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_incref ("taxes", - (json_t *) taxes)), - GNUNET_JSON_pack_string ("unit_total_stock", - unit_total_stock_buf), - GNUNET_JSON_pack_bool ("unit_allow_fraction", - unit_allow_fraction), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_uint64 ("minimum_age", - minimum_age)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("address", - (json_t *) address)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_timestamp ("next_restock", - next_restock))); + unit_prices = ppph->unit_prices; + unit_price_len = ppph->unit_prices_len; } - if (NULL != unit_precision_level) + 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), + GNUNET_JSON_pack_string ("description", + ppph->description), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_incref ("description_i18n", + (json_t *) 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), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_array_incref ("taxes", + (json_t *) 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)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("next_restock", + ppph->have_next_restock + ? ppph->next_restock + : GNUNET_TIME_UNIT_ZERO_TS))); + if (ppph->have_minimum_age) { GNUNET_assert (0 == json_object_set_new (req_obj, - "unit_precision_level", + "minimum_age", json_integer ( - *unit_precision_level))); + ppph->minimum_age))); } - if (! unit_allow_fraction) + if (ppph->have_unit_allow_fraction && + ppph->unit_allow_fraction) { GNUNET_assert (0 == - json_object_del (req_obj, - "unit_allow_fraction")); - if (NULL != unit_precision_level) + json_object_set_new (req_obj, + "unit_allow_fraction", + json_true ())); + if (ppph->have_unit_precision_level) + { GNUNET_assert (0 == - json_object_del (req_obj, - "unit_precision_level")); + json_object_set_new (req_obj, + "unit_precision_level", + json_integer ( + ppph->unit_precision_level))); + } } - pph = GNUNET_new (struct TALER_MERCHANT_ProductsPostHandle); - pph->ctx = ctx; - pph->cb = cb; - pph->cb_cls = cb_cls; - pph->url = TALER_url_join (backend_url, - "private/products", - NULL); - if (NULL == pph->url) + eh = TALER_MERCHANT_curl_easy_get_ (ppph->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppph->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (pph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (pph->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&pph->post_ctx, - eh, - req_obj)); + GNUNET_break (0); json_decref (req_obj); - pph->job = GNUNET_CURL_job_add2 (ctx, - eh, - pph->post_ctx.headers, - &handle_post_products_finished, - pph); - GNUNET_assert (NULL != pph->job); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return pph; -} - - -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post3 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_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, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - uint32_t minimum_age, - unsigned int num_cats, - const uint64_t *cats, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls) -{ - return TALER_MERCHANT_products_post4 (ctx, - backend_url, - product_id, - description, - description_i18n, - unit, - price, - 1, - image, - taxes, - total_stock, - 0, - false, - NULL, - address, - next_restock, - minimum_age, - num_cats, - cats, - cb, - cb_cls); -} - - -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_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, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - uint32_t minimum_age, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls) -{ - return TALER_MERCHANT_products_post3 (ctx, - backend_url, - product_id, - description, - description_i18n, - unit, - price, - image, - taxes, - total_stock, - address, - next_restock, - minimum_age, - 0, - NULL, - cb, - cb_cls); -} - - -struct TALER_MERCHANT_ProductsPostHandle * -TALER_MERCHANT_products_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_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, - const json_t *address, - struct GNUNET_TIME_Timestamp next_restock, - TALER_MERCHANT_ProductsPostCallback cb, - void *cb_cls) -{ - return TALER_MERCHANT_products_post2 (ctx, - backend_url, - product_id, - description, - description_i18n, - unit, - price, - image, - taxes, - total_stock, - address, - next_restock, - 0, - cb, - cb_cls); + json_decref (req_obj); + ppph->job = GNUNET_CURL_job_add2 (ppph->ctx, + eh, + ppph->post_ctx.headers, + &handle_post_products_finished, + ppph); + if (NULL == ppph->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_products_post_cancel ( - struct TALER_MERCHANT_ProductsPostHandle *pph) +TALER_MERCHANT_post_private_products_cancel ( + struct TALER_MERCHANT_PostPrivateProductsHandle *ppph) { - if (NULL != pph->job) + if (NULL != ppph->job) { - GNUNET_CURL_job_cancel (pph->job); - pph->job = NULL; + GNUNET_CURL_job_cancel (ppph->job); + ppph->job = NULL; } - TALER_curl_easy_post_finished (&pph->post_ctx); - GNUNET_free (pph->url); - GNUNET_free (pph); + TALER_curl_easy_post_finished (&ppph->post_ctx); + GNUNET_free (ppph->product_id); + GNUNET_free (ppph->description); + GNUNET_free (ppph->unit); + GNUNET_free (ppph->image); + GNUNET_free (ppph->url); + GNUNET_free (ppph->base_url); + GNUNET_free (ppph); } -/* end of merchant_api_post_products.c */ +/* end of merchant_api_post-private-products-new.c */ diff --git a/src/lib/merchant_api_post-private-templates-new.c b/src/lib/merchant_api_post-private-templates-new.c @@ -1,287 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-templates-new.c - * @brief Implementation of the POST /private/templates request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-templates-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/templates operation. - */ -struct TALER_MERCHANT_PostPrivateTemplatesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateTemplatesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Template identifier. - */ - char *template_id; - - /** - * Human-readable description. - */ - char *template_description; - - /** - * Template contract (JSON). - */ - json_t *template_contract; - - /** - * Optional OTP device ID. - */ - char *otp_id; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/templates request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateTemplatesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_templates_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateTemplatesResponse ptr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/templates completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - GNUNET_break_op (0); - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - 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); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &ptr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ptr.hr.ec); - GNUNET_break_op (0); - break; - } - ppth->cb (ppth->cb_cls, - &ptr); - TALER_MERCHANT_post_private_templates_cancel (ppth); -} - - -struct TALER_MERCHANT_PostPrivateTemplatesHandle * -TALER_MERCHANT_post_private_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id, - const char *template_description, - const json_t *template_contract) -{ - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth; - - ppth = GNUNET_new (struct TALER_MERCHANT_PostPrivateTemplatesHandle); - ppth->ctx = ctx; - ppth->base_url = GNUNET_strdup (url); - ppth->template_id = GNUNET_strdup (template_id); - ppth->template_description = GNUNET_strdup (template_description); - ppth->template_contract = json_incref ((json_t *) template_contract); - return ppth; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_templates_set_options_ ( - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID: - ppth->otp_id = GNUNET_strdup (options[i].details.otp_id); - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_templates_start ( - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, - TALER_MERCHANT_PostPrivateTemplatesCallback cb, - TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppth->cb = cb; - ppth->cb_cls = cb_cls; - ppth->url = TALER_url_join (ppth->base_url, - "private/templates", - NULL); - if (NULL == ppth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("template_id", - ppth->template_id), - GNUNET_JSON_pack_string ("template_description", - ppth->template_description), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("otp_id", - ppth->otp_id)), - GNUNET_JSON_pack_object_incref ("template_contract", - ppth->template_contract)); - eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppth->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppth->job = GNUNET_CURL_job_add2 (ppth->ctx, - eh, - ppth->post_ctx.headers, - &handle_post_templates_finished, - ppth); - if (NULL == ppth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_templates_cancel ( - struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth) -{ - if (NULL != ppth->job) - { - GNUNET_CURL_job_cancel (ppth->job); - ppth->job = NULL; - } - TALER_curl_easy_post_finished (&ppth->post_ctx); - json_decref (ppth->template_contract); - GNUNET_free (ppth->template_id); - GNUNET_free (ppth->template_description); - GNUNET_free (ppth->otp_id); - GNUNET_free (ppth->url); - GNUNET_free (ppth->base_url); - GNUNET_free (ppth); -} - - -/* end of merchant_api_post-private-templates-new.c */ diff --git a/src/lib/merchant_api_post-private-templates.c b/src/lib/merchant_api_post-private-templates.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,221 +17,35 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-templates.c - * @brief Implementation of the POST /templates request - * of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_post-private-templates-new.c + * @brief Implementation of the POST /private/templates request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-templates.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> -#include "taler/taler_merchant_util.h" - -/* FIXME: Bohdan is to stupid to figure out how util can be used here */ -static enum TALER_MERCHANT_TemplateType -template_type_from_string (const char *template_type) -{ - if (NULL == template_type) - return TALER_MERCHANT_TEMPLATE_TYPE_FIXED_ORDER; - if (0 == strcmp (template_type, - "fixed-order")) - return TALER_MERCHANT_TEMPLATE_TYPE_FIXED_ORDER; - if (0 == strcmp (template_type, - "inventory-cart")) - return TALER_MERCHANT_TEMPLATE_TYPE_INVENTORY_CART; - if (0 == strcmp (template_type, - "paivana")) - return TALER_MERCHANT_TEMPLATE_TYPE_PAIVANA; - return TALER_MERCHANT_TEMPLATE_TYPE_INVALID; -} - - -/** - * Validate a fixed-order template contract. - * - * @param template_contract JSON template contract - * @param summary summary pointer - * @param amount amount storage - * @param minimum_age minimum age storage - * @param pay_duration pay duration storage - * @return true if valid - */ -static bool -validate_template_contract_fixed (const json_t *template_contract, - const char **summary, - struct TALER_Amount *amount, - uint32_t *minimum_age, - struct GNUNET_TIME_Relative *pay_duration) -{ - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("summary", - summary), - NULL), - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_amount_any ("amount", - amount), - NULL), - GNUNET_JSON_spec_uint32 ("minimum_age", - minimum_age), - GNUNET_JSON_spec_relative_time ("pay_duration", - pay_duration), - GNUNET_JSON_spec_end () - }; - const char *ename; - unsigned int eline; - - if (GNUNET_OK != - GNUNET_JSON_parse (template_contract, - spec, - &ename, - &eline)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid template_contract for field %s\n", - ename); - return false; - } - return true; -} /** - * Validate an inventory-cart template contract. - * - * @param template_contract JSON template contract - * @param summary summary pointer - * @param pay_duration pay duration storage - * @return true if valid + * Handle for a POST /private/templates operation. */ -static bool -validate_template_contract_inventory (const json_t *template_contract, - const char **summary, - struct GNUNET_TIME_Relative *pay_duration) -{ - bool selected_all = false; - bool choose_one = false; - bool request_tip = false; - const json_t *selected_categories = NULL; - const json_t *selected_products = NULL; - struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("summary", - summary), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("request_tip", - &request_tip), - NULL), - GNUNET_JSON_spec_relative_time ("pay_duration", - pay_duration), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("selected_all", - &selected_all), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ("selected_categories", - &selected_categories), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_array_const ("selected_products", - &selected_products), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("choose_one", - &choose_one), - NULL), - GNUNET_JSON_spec_end () - }; - const char *ename; - unsigned int eline; - - (void) request_tip; - (void) selected_all; - (void) choose_one; - (void) selected_categories; - (void) selected_products; - if (GNUNET_OK != - GNUNET_JSON_parse (template_contract, - ispec, - &ename, - &eline)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid template_contract for field %s\n", - ename); - return false; - } - return true; -} - - -/** - * Validate a paivana template contract. - * - * @param template_contract JSON template contract - * @param summary summary pointer - * @param amount amount storage - * @param minimum_age minimum age storage - * @param pay_duration pay duration storage - * @return true if valid - */ -static bool -validate_template_contract_paivana (const json_t *template_contract, - const char **summary, - struct TALER_Amount *amount, - uint32_t *minimum_age, - struct GNUNET_TIME_Relative *pay_duration) -{ - /* TODO: PAIVANA validate paivana-specific fields beyond presence. */ - const char *paivana_id; - struct GNUNET_JSON_Specification pspec[] = { - GNUNET_JSON_spec_string ("paivana_id", - &paivana_id), - GNUNET_JSON_spec_end () - }; - const char *ename; - unsigned int eline; - - if (GNUNET_OK != - GNUNET_JSON_parse (template_contract, - pspec, - &ename, - &eline)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid paivana template_contract for field %s\n", - ename); - return false; - } - - if (! validate_template_contract_fixed (template_contract, - summary, - amount, - minimum_age, - pay_duration)) - return false; - - (void) paivana_id; - return true; -} - - -/** - * Handle for a POST /templates/$ID operation. - */ -struct TALER_MERCHANT_TemplatesPostHandle +struct TALER_MERCHANT_PostPrivateTemplatesHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -243,12 +57,12 @@ struct TALER_MERCHANT_TemplatesPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_TemplatesPostCallback cb; + TALER_MERCHANT_PostPrivateTemplatesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -259,14 +73,34 @@ struct TALER_MERCHANT_TemplatesPostHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Template identifier. + */ + char *template_id; + + /** + * Human-readable description. + */ + char *template_description; + + /** + * Template contract (JSON). + */ + json_t *template_contract; + + /** + * Optional OTP device ID. + */ + char *otp_id; }; /** * Function called when we're done processing the - * HTTP POST /templates request. + * HTTP POST /private/templates request. * - * @param cls the `struct TALER_MERCHANT_TemplatesPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateTemplatesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -275,221 +109,179 @@ handle_post_templates_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_TemplatesPostHandle *tph = cls; + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateTemplatesResponse ptr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - tph->job = NULL; + ppth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /templates completed with response code %u\n", + "POST /private/templates completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + GNUNET_break_op (0); + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + 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: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &ptr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) ptr.hr.ec); GNUNET_break_op (0); break; } - tph->cb (tph->cb_cls, - &hr); - TALER_MERCHANT_templates_post_cancel (tph); + ppth->cb (ppth->cb_cls, + &ptr); + TALER_MERCHANT_post_private_templates_cancel (ppth); } -static bool -test_template_contract_valid (const json_t *template_contract) +struct TALER_MERCHANT_PostPrivateTemplatesHandle * +TALER_MERCHANT_post_private_templates_create ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *template_id, + const char *template_description, + const json_t *template_contract) { - const char *template_type = NULL; - enum TALER_MERCHANT_TemplateType template_type_enum; - struct GNUNET_JSON_Specification type_spec[] = { - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("template_type", - &template_type), - NULL), - GNUNET_JSON_spec_end () - }; - const char *summary; - struct TALER_Amount amount = { .value = 0}; - uint32_t minimum_age = 0; - struct GNUNET_TIME_Relative pay_duration = { 0 }; - const char *ename; - unsigned int eline; - - if (GNUNET_OK != - GNUNET_JSON_parse (template_contract, - type_spec, - &ename, - &eline)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid template_contract for field %s\n", - ename); - return false; - } + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth; + + ppth = GNUNET_new (struct TALER_MERCHANT_PostPrivateTemplatesHandle); + ppth->ctx = ctx; + ppth->base_url = GNUNET_strdup (url); + ppth->template_id = GNUNET_strdup (template_id); + ppth->template_description = GNUNET_strdup (template_description); + ppth->template_contract = json_incref ((json_t *) template_contract); + return ppth; +} - template_type_enum = template_type_from_string (template_type); - if (TALER_MERCHANT_TEMPLATE_TYPE_INVALID == template_type_enum) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid template_type '%s'\n", - template_type); - return false; - } - /* FIXME: Bohdan understands that links have to be changed, but worried, that can crash something */ - switch (template_type_enum) +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_templates_set_options_ ( + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateTemplatesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) { - case TALER_MERCHANT_TEMPLATE_TYPE_INVENTORY_CART: - return validate_template_contract_inventory (template_contract, - &summary, - &pay_duration); - case TALER_MERCHANT_TEMPLATE_TYPE_FIXED_ORDER: - return validate_template_contract_fixed (template_contract, - &summary, - &amount, - &minimum_age, - &pay_duration); - case TALER_MERCHANT_TEMPLATE_TYPE_PAIVANA: - return validate_template_contract_paivana (template_contract, - &summary, - &amount, - &minimum_age, - &pay_duration); - case TALER_MERCHANT_TEMPLATE_TYPE_INVALID: - break; + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_TEMPLATES_OPTION_OTP_ID: + ppth->otp_id = GNUNET_strdup (options[i].details.otp_id); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } } - return false; + return GNUNET_OK; } -struct TALER_MERCHANT_TemplatesPostHandle * -TALER_MERCHANT_templates_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - const char *template_description, - const char *otp_id, - const json_t *template_contract, - TALER_MERCHANT_TemplatesPostCallback cb, - void *cb_cls) +enum TALER_ErrorCode +TALER_MERCHANT_post_private_templates_start ( + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth, + TALER_MERCHANT_PostPrivateTemplatesCallback cb, + TALER_MERCHANT_POST_PRIVATE_TEMPLATES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TemplatesPostHandle *tph; json_t *req_obj; - - if (! test_template_contract_valid (template_contract)) - { - GNUNET_break (0); - return NULL; - } + CURL *eh; + + ppth->cb = cb; + ppth->cb_cls = cb_cls; + ppth->url = TALER_url_join (ppth->base_url, + "private/templates", + NULL); + if (NULL == ppth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("template_id", - template_id), + ppth->template_id), GNUNET_JSON_pack_string ("template_description", - template_description), + ppth->template_description), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("otp_id", - otp_id)), + ppth->otp_id)), GNUNET_JSON_pack_object_incref ("template_contract", - (json_t *) template_contract)); - tph = GNUNET_new (struct TALER_MERCHANT_TemplatesPostHandle); - tph->ctx = ctx; - tph->cb = cb; - tph->cb_cls = cb_cls; - tph->url = TALER_url_join (backend_url, - "private/templates", - NULL); - if (NULL == tph->url) + ppth->template_contract)); + eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppth->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (tph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (tph->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&tph->post_ctx, - eh, - req_obj)); + GNUNET_break (0); json_decref (req_obj); - tph->job = GNUNET_CURL_job_add2 (ctx, - eh, - tph->post_ctx.headers, - &handle_post_templates_finished, - tph); - GNUNET_assert (NULL != tph->job); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return tph; + json_decref (req_obj); + ppth->job = GNUNET_CURL_job_add2 (ppth->ctx, + eh, + ppth->post_ctx.headers, + &handle_post_templates_finished, + ppth); + if (NULL == ppth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_templates_post_cancel ( - struct TALER_MERCHANT_TemplatesPostHandle *tph) +TALER_MERCHANT_post_private_templates_cancel ( + struct TALER_MERCHANT_PostPrivateTemplatesHandle *ppth) { - if (NULL != tph->job) + if (NULL != ppth->job) { - GNUNET_CURL_job_cancel (tph->job); - tph->job = NULL; + GNUNET_CURL_job_cancel (ppth->job); + ppth->job = NULL; } - TALER_curl_easy_post_finished (&tph->post_ctx); - GNUNET_free (tph->url); - GNUNET_free (tph); + TALER_curl_easy_post_finished (&ppth->post_ctx); + json_decref (ppth->template_contract); + GNUNET_free (ppth->template_id); + GNUNET_free (ppth->template_description); + GNUNET_free (ppth->otp_id); + GNUNET_free (ppth->url); + GNUNET_free (ppth->base_url); + GNUNET_free (ppth); } -/* end of merchant_api_post_templates.c */ +/* end of merchant_api_post-private-templates-new.c */ diff --git a/src/lib/merchant_api_post-private-token-new.c b/src/lib/merchant_api_post-private-token-new.c @@ -1,258 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-token-new.c - * @brief Implementation of the POST /private/token request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-token-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/token operation. - */ -struct TALER_MERCHANT_PostPrivateTokenHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateTokenCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Instance identifier (or NULL). - */ - char *instance_id; - - /** - * Scope for the token. - */ - char *scope; - - /** - * How long the token should be valid. - */ - struct GNUNET_TIME_Relative duration; - - /** - * Whether the token may be refreshed. - */ - bool refreshable; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/token request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateTokenHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_token_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateTokenHandle *ppth = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateTokenResponse ptr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppth->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "POST /private/token completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case MHD_HTTP_OK: - break; - case MHD_HTTP_BAD_REQUEST: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ptr.hr.ec); - break; - } - ppth->cb (ppth->cb_cls, - &ptr); - TALER_MERCHANT_post_private_token_cancel (ppth); -} - - -struct TALER_MERCHANT_PostPrivateTokenHandle * -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) -{ - struct TALER_MERCHANT_PostPrivateTokenHandle *ppth; - - ppth = GNUNET_new (struct TALER_MERCHANT_PostPrivateTokenHandle); - ppth->ctx = ctx; - ppth->base_url = GNUNET_strdup (url); - 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 TALER_ErrorCode -TALER_MERCHANT_post_private_token_start ( - struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, - TALER_MERCHANT_PostPrivateTokenCallback cb, - TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppth->cb = cb; - ppth->cb_cls = cb_cls; - if (NULL != ppth->instance_id) - { - char *path; - - GNUNET_asprintf (&path, - "instances/%s/private/token", - ppth->instance_id); - ppth->url = TALER_url_join (ppth->base_url, - path, - NULL); - GNUNET_free (path); - } - else - { - ppth->url = TALER_url_join (ppth->base_url, - "private/token", - NULL); - } - 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)); - eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppth->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_POST)); - ppth->job = GNUNET_CURL_job_add2 (ppth->ctx, - eh, - ppth->post_ctx.headers, - &handle_post_token_finished, - ppth); - if (NULL == ppth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_token_cancel ( - struct TALER_MERCHANT_PostPrivateTokenHandle *ppth) -{ - if (NULL != ppth->job) - { - GNUNET_CURL_job_cancel (ppth->job); - ppth->job = NULL; - } - TALER_curl_easy_post_finished (&ppth->post_ctx); - GNUNET_free (ppth->instance_id); - GNUNET_free (ppth->scope); - GNUNET_free (ppth->url); - GNUNET_free (ppth->base_url); - GNUNET_free (ppth); -} - - -/* end of merchant_api_post-private-token-new.c */ diff --git a/src/lib/merchant_api_post-private-token.c b/src/lib/merchant_api_post-private-token.c @@ -1,23 +1,25 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1, + or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + TALER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> + You should have received a copy of the GNU Lesser General + Public License along with TALER; see the file COPYING.LGPL. + If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-token.c - * @brief Implementation of the POST /instance/$ID/private/token request - * @author Martin Schanzenbach + * @file merchant_api_post-private-token-new.c + * @brief Implementation of the POST /private/token request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> @@ -25,20 +27,25 @@ #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_curl_lib.h> -#include "taler/taler_merchant_service.h" +#include <taler/taler-merchant/post-private-token.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> -#include <taler/taler_signatures.h> #include <taler/taler_curl_lib.h> /** - * Handle for a POST /instances/$ID/private/token operation. + * Handle for a POST /private/token operation. */ -struct TALER_MERCHANT_InstanceTokenPostHandle +struct TALER_MERCHANT_PostPrivateTokenHandle { /** - * The url for this request. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; @@ -50,12 +57,12 @@ struct TALER_MERCHANT_InstanceTokenPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_InstanceTokenPostCallback cb; + TALER_MERCHANT_PostPrivateTokenCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -67,169 +74,185 @@ struct TALER_MERCHANT_InstanceTokenPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Instance identifier (or NULL). + */ + char *instance_id; + + /** + * Scope for the token. + */ + char *scope; + + /** + * How long the token should be valid. + */ + struct GNUNET_TIME_Relative duration; + + /** + * Whether the token may be refreshed. + */ + bool refreshable; }; /** * Function called when we're done processing the - * HTTP GET /instances/$ID/private/token request. + * HTTP POST /private/token request. * - * @param cls the `struct TALER_MERCHANT_InstanceTokenPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateTokenHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_post_instance_token_finished (void *cls, - long response_code, - const void *response) +handle_post_token_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_InstanceTokenPostHandle *itph = cls; + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateTokenResponse ptr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - itph->job = NULL; + ppth->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /instances/$ID response with status code %u\n", + "POST /private/token completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case MHD_HTTP_OK: break; case MHD_HTTP_BAD_REQUEST: - /* happens if the auth token is malformed */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) ptr.hr.ec); break; } - itph->cb (itph->cb_cls, - &hr); - TALER_MERCHANT_instance_token_post_cancel (itph); + ppth->cb (ppth->cb_cls, + &ptr); + TALER_MERCHANT_post_private_token_cancel (ppth); } -struct TALER_MERCHANT_InstanceTokenPostHandle * -TALER_MERCHANT_instance_token_post ( +struct TALER_MERCHANT_PostPrivateTokenHandle * +TALER_MERCHANT_post_private_token_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *instance_id, const char *scope, struct GNUNET_TIME_Relative duration, - bool refreshable, - TALER_MERCHANT_InstanceTokenPostCallback cb, - void *cb_cls) + bool refreshable) { - struct TALER_MERCHANT_InstanceTokenPostHandle *itph; - json_t *req_obj; + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth; - itph = GNUNET_new (struct TALER_MERCHANT_InstanceTokenPostHandle); - itph->ctx = ctx; - itph->cb = cb; - itph->cb_cls = cb_cls; + ppth = GNUNET_new (struct TALER_MERCHANT_PostPrivateTokenHandle); + ppth->ctx = ctx; + ppth->base_url = GNUNET_strdup (url); 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 TALER_ErrorCode +TALER_MERCHANT_post_private_token_start ( + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth, + TALER_MERCHANT_PostPrivateTokenCallback cb, + TALER_MERCHANT_POST_PRIVATE_TOKEN_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; + CURL *eh; + + ppth->cb = cb; + ppth->cb_cls = cb_cls; + if (NULL != ppth->instance_id) { char *path; GNUNET_asprintf (&path, "instances/%s/private/token", - instance_id); - itph->url = TALER_url_join (backend_url, + ppth->instance_id); + ppth->url = TALER_url_join (ppth->base_url, path, NULL); GNUNET_free (path); } else { - /* backend_url is already identifying the instance */ - itph->url = TALER_url_join (backend_url, + ppth->url = TALER_url_join (ppth->base_url, "private/token", NULL); } - if (NULL == itph->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (itph); - return NULL; - } - if (NULL == scope) - { - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_time_rel ("duration", - duration), - GNUNET_JSON_pack_bool ("refreshable", - refreshable), - GNUNET_JSON_pack_string ("scope", - "readonly")); - } - else - { - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_time_rel ("duration", - duration), - GNUNET_JSON_pack_bool ("refreshable", - refreshable), - GNUNET_JSON_pack_string ("scope", - scope)); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Requesting URL '%s'\n", - itph->url); - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (itph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&itph->post_ctx, + 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)); + eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppth->post_ctx, eh, - req_obj)) - { - GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (itph->url); - GNUNET_free (itph); - return NULL; - } + req_obj)) ) + { + GNUNET_break (0); json_decref (req_obj); - GNUNET_assert (CURLE_OK == - curl_easy_setopt (eh, - CURLOPT_CUSTOMREQUEST, - MHD_HTTP_METHOD_POST)); - itph->job = GNUNET_CURL_job_add2 (ctx, - eh, - itph->post_ctx.headers, - &handle_post_instance_token_finished, - itph); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return itph; + json_decref (req_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_CUSTOMREQUEST, + MHD_HTTP_METHOD_POST)); + ppth->job = GNUNET_CURL_job_add2 (ppth->ctx, + eh, + ppth->post_ctx.headers, + &handle_post_token_finished, + ppth); + if (NULL == ppth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_instance_token_post_cancel ( - struct TALER_MERCHANT_InstanceTokenPostHandle *itph) +TALER_MERCHANT_post_private_token_cancel ( + struct TALER_MERCHANT_PostPrivateTokenHandle *ppth) { - if (NULL != itph->job) - GNUNET_CURL_job_cancel (itph->job); - TALER_curl_easy_post_finished (&itph->post_ctx); - GNUNET_free (itph->url); - GNUNET_free (itph); + if (NULL != ppth->job) + { + GNUNET_CURL_job_cancel (ppth->job); + ppth->job = NULL; + } + TALER_curl_easy_post_finished (&ppth->post_ctx); + GNUNET_free (ppth->instance_id); + GNUNET_free (ppth->scope); + GNUNET_free (ppth->url); + GNUNET_free (ppth->base_url); + GNUNET_free (ppth); } + + +/* end of merchant_api_post-private-token-new.c */ diff --git a/src/lib/merchant_api_post-private-tokenfamilies-new.c b/src/lib/merchant_api_post-private-tokenfamilies-new.c @@ -1,357 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2020-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-tokenfamilies-new.c - * @brief Implementation of the POST /private/tokenfamilies request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-tokenfamilies-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/tokenfamilies operation. - */ -struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateTokenfamiliesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * URL-safe slug identifier. - */ - char *slug; - - /** - * Human-readable name. - */ - char *name; - - /** - * Human-readable description. - */ - char *description; - - /** - * Start of validity period. - */ - struct GNUNET_TIME_Timestamp valid_after; - - /** - * End of validity period. - */ - struct GNUNET_TIME_Timestamp valid_before; - - /** - * Duration of individual token validity. - */ - struct GNUNET_TIME_Relative duration; - - /** - * Granularity for validity alignment. - */ - struct GNUNET_TIME_Relative validity_granularity; - - /** - * Offset from purchase to start of validity. - */ - struct GNUNET_TIME_Relative start_offset; - - /** - * Kind of token family. - */ - char *kind; - - /** - * Optional internationalized descriptions (JSON). - */ - json_t *description_i18n; - - /** - * Optional extra data (JSON). - */ - json_t *extra_data; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/tokenfamilies request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_tokenfamilies_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateTokenfamiliesResponse tfr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ptfh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/tokenfamilies completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - tfr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - GNUNET_break_op (0); - tfr.hr.ec = TALER_JSON_get_error_code (json); - tfr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - tfr.hr.ec = TALER_JSON_get_error_code (json); - tfr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - tfr.hr.ec = TALER_JSON_get_error_code (json); - tfr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - tfr.hr.ec = TALER_JSON_get_error_code (json); - tfr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - tfr.hr.ec = TALER_JSON_get_error_code (json); - tfr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - tfr.hr.ec = TALER_JSON_get_error_code (json); - tfr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &tfr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) tfr.hr.ec); - GNUNET_break_op (0); - break; - } - ptfh->cb (ptfh->cb_cls, - &tfr); - TALER_MERCHANT_post_private_tokenfamilies_cancel (ptfh); -} - - -struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle * -TALER_MERCHANT_post_private_tokenfamilies_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *slug, - const char *name, - const char *description, - struct GNUNET_TIME_Timestamp valid_after, - struct GNUNET_TIME_Timestamp valid_before, - struct GNUNET_TIME_Relative duration, - struct GNUNET_TIME_Relative validity_granularity, - struct GNUNET_TIME_Relative start_offset, - const char *kind) -{ - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh; - - ptfh = GNUNET_new (struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle); - ptfh->ctx = ctx; - ptfh->base_url = GNUNET_strdup (url); - ptfh->slug = GNUNET_strdup (slug); - ptfh->name = GNUNET_strdup (name); - ptfh->description = GNUNET_strdup (description); - ptfh->valid_after = valid_after; - ptfh->valid_before = valid_before; - ptfh->duration = duration; - ptfh->validity_granularity = validity_granularity; - ptfh->start_offset = start_offset; - ptfh->kind = GNUNET_strdup (kind); - return ptfh; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_tokenfamilies_set_options_ ( - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N: - ptfh->description_i18n - = json_incref ((json_t *) options[i].details.description_i18n); - break; - case TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA: - ptfh->extra_data - = json_incref ((json_t *) options[i].details.extra_data); - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_tokenfamilies_start ( - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, - TALER_MERCHANT_PostPrivateTokenfamiliesCallback cb, - TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ptfh->cb = cb; - ptfh->cb_cls = cb_cls; - ptfh->url = TALER_url_join (ptfh->base_url, - "private/tokenfamilies", - NULL); - if (NULL == ptfh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("slug", - ptfh->slug), - GNUNET_JSON_pack_string ("name", - ptfh->name), - GNUNET_JSON_pack_string ("description", - ptfh->description), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("description_i18n", - ptfh->description_i18n)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("extra_data", - ptfh->extra_data)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_timestamp ("valid_after", - ptfh->valid_after)), - GNUNET_JSON_pack_timestamp ("valid_before", - ptfh->valid_before), - GNUNET_JSON_pack_time_rel ("duration", - ptfh->duration), - GNUNET_JSON_pack_time_rel ("validity_granularity", - ptfh->validity_granularity), - GNUNET_JSON_pack_time_rel ("start_offset", - ptfh->start_offset), - GNUNET_JSON_pack_string ("kind", - ptfh->kind)); - eh = TALER_MERCHANT_curl_easy_get_ (ptfh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ptfh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ptfh->job = GNUNET_CURL_job_add2 (ptfh->ctx, - eh, - ptfh->post_ctx.headers, - &handle_post_tokenfamilies_finished, - ptfh); - if (NULL == ptfh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_tokenfamilies_cancel ( - struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh) -{ - if (NULL != ptfh->job) - { - GNUNET_CURL_job_cancel (ptfh->job); - ptfh->job = NULL; - } - TALER_curl_easy_post_finished (&ptfh->post_ctx); - json_decref (ptfh->description_i18n); - json_decref (ptfh->extra_data); - GNUNET_free (ptfh->slug); - GNUNET_free (ptfh->name); - GNUNET_free (ptfh->description); - GNUNET_free (ptfh->kind); - GNUNET_free (ptfh->url); - GNUNET_free (ptfh->base_url); - GNUNET_free (ptfh); -} - - -/* end of merchant_api_post-private-tokenfamilies-new.c */ diff --git a/src/lib/merchant_api_post-private-tokenfamilies.c b/src/lib/merchant_api_post-private-tokenfamilies.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2024 Taler Systems SA + Copyright (C) 2020-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,19 +17,17 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-tokenfamilies.c - * @brief Implementation of the POST /tokenfamilies request - * of the merchant's HTTP API - * @author Christian Blättler + * @file merchant_api_post-private-tokenfamilies-new.c + * @brief Implementation of the POST /private/tokenfamilies request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> -#include <gnunet/gnunet_json_lib.h> -#include <gnunet/gnunet_time_lib.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-tokenfamilies.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -37,13 +35,17 @@ /** - * Handle for a POST /tokenfamilies operation. + * Handle for a POST /private/tokenfamilies operation. */ -struct TALER_MERCHANT_TokenFamiliesPostHandle +struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -55,12 +57,12 @@ struct TALER_MERCHANT_TokenFamiliesPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_TokenFamiliesPostCallback cb; + TALER_MERCHANT_PostPrivateTokenfamiliesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -72,186 +74,284 @@ struct TALER_MERCHANT_TokenFamiliesPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * URL-safe slug identifier. + */ + char *slug; + + /** + * Human-readable name. + */ + char *name; + + /** + * Human-readable description. + */ + char *description; + + /** + * Start of validity period. + */ + struct GNUNET_TIME_Timestamp valid_after; + + /** + * End of validity period. + */ + struct GNUNET_TIME_Timestamp valid_before; + + /** + * Duration of individual token validity. + */ + struct GNUNET_TIME_Relative duration; + + /** + * Granularity for validity alignment. + */ + struct GNUNET_TIME_Relative validity_granularity; + + /** + * Offset from purchase to start of validity. + */ + struct GNUNET_TIME_Relative start_offset; + + /** + * Kind of token family. + */ + char *kind; + + /** + * Optional internationalized descriptions (JSON). + */ + json_t *description_i18n; + + /** + * Optional extra data (JSON). + */ + json_t *extra_data; }; + /** * Function called when we're done processing the - * HTTP POST /tokenfamilies request. + * HTTP POST /private/tokenfamilies request. * - * @param cls the `struct TALER_MERCHANT_TokenFamiliesPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_post_token_families_finished (void *cls, - long response_code, - const void *response) +handle_post_tokenfamilies_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_TokenFamiliesPostHandle *handle = cls; + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateTokenfamiliesResponse tfr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - handle->job = NULL; + ptfh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /tokenfamilies completed with response code %u\n", + "POST /private/tokenfamilies completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + tfr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + GNUNET_break_op (0); + tfr.hr.ec = TALER_JSON_get_error_code (json); + tfr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + tfr.hr.ec = TALER_JSON_get_error_code (json); + tfr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + tfr.hr.ec = TALER_JSON_get_error_code (json); + tfr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ + tfr.hr.ec = TALER_JSON_get_error_code (json); + tfr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tfr.hr.ec = TALER_JSON_get_error_code (json); + tfr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + tfr.hr.ec = TALER_JSON_get_error_code (json); + tfr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &tfr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) tfr.hr.ec); GNUNET_break_op (0); break; } - handle->cb (handle->cb_cls, - &hr); - TALER_MERCHANT_token_families_post_cancel (handle); + ptfh->cb (ptfh->cb_cls, + &tfr); + TALER_MERCHANT_post_private_tokenfamilies_cancel (ptfh); } -struct TALER_MERCHANT_TokenFamiliesPostHandle * -TALER_MERCHANT_token_families_post ( +struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle * +TALER_MERCHANT_post_private_tokenfamilies_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *slug, const char *name, const char *description, - const json_t *description_i18n, - const json_t *extra_data, struct GNUNET_TIME_Timestamp valid_after, struct GNUNET_TIME_Timestamp valid_before, struct GNUNET_TIME_Relative duration, struct GNUNET_TIME_Relative validity_granularity, struct GNUNET_TIME_Relative start_offset, - const char *kind, - TALER_MERCHANT_TokenFamiliesPostCallback cb, - void *cb_cls) + const char *kind) +{ + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh; + + ptfh = GNUNET_new (struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle); + ptfh->ctx = ctx; + ptfh->base_url = GNUNET_strdup (url); + ptfh->slug = GNUNET_strdup (slug); + ptfh->name = GNUNET_strdup (name); + ptfh->description = GNUNET_strdup (description); + ptfh->valid_after = valid_after; + ptfh->valid_before = valid_before; + ptfh->duration = duration; + ptfh->validity_granularity = validity_granularity; + ptfh->start_offset = start_offset; + ptfh->kind = GNUNET_strdup (kind); + return ptfh; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_tokenfamilies_set_options_ ( + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateTokenfamiliesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_DESCRIPTION_I18N: + ptfh->description_i18n + = json_incref ((json_t *) options[i].details.description_i18n); + break; + case TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_OPTION_EXTRA_DATA: + ptfh->extra_data + = json_incref ((json_t *) options[i].details.extra_data); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_tokenfamilies_start ( + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh, + TALER_MERCHANT_PostPrivateTokenfamiliesCallback cb, + TALER_MERCHANT_POST_PRIVATE_TOKENFAMILIES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_TokenFamiliesPostHandle *handle; json_t *req_obj; + CURL *eh; + ptfh->cb = cb; + ptfh->cb_cls = cb_cls; + ptfh->url = TALER_url_join (ptfh->base_url, + "private/tokenfamilies", + NULL); + if (NULL == ptfh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("slug", - slug), + ptfh->slug), GNUNET_JSON_pack_string ("name", - name), + ptfh->name), GNUNET_JSON_pack_string ("description", - description), + ptfh->description), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("description_i18n", - (json_t *) description_i18n)), + ptfh->description_i18n)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("extra_data", - (json_t *) extra_data)), + ptfh->extra_data)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_timestamp ("valid_after", - valid_after)), + ptfh->valid_after)), GNUNET_JSON_pack_timestamp ("valid_before", - valid_before), + ptfh->valid_before), GNUNET_JSON_pack_time_rel ("duration", - duration), + ptfh->duration), GNUNET_JSON_pack_time_rel ("validity_granularity", - validity_granularity), + ptfh->validity_granularity), GNUNET_JSON_pack_time_rel ("start_offset", - start_offset), + ptfh->start_offset), GNUNET_JSON_pack_string ("kind", - kind)); - handle = GNUNET_new (struct TALER_MERCHANT_TokenFamiliesPostHandle); - handle->ctx = ctx; - handle->cb = cb; - handle->cb_cls = cb_cls; - handle->url = TALER_url_join (backend_url, - "private/tokenfamilies", - NULL); - if (NULL == handle->url) + ptfh->kind)); + eh = TALER_MERCHANT_curl_easy_get_ (ptfh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ptfh->post_ctx, + eh, + req_obj)) ) { - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (handle); - return NULL; + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (handle->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&handle->post_ctx, - eh, - req_obj)); - json_decref (req_obj); - handle->job = GNUNET_CURL_job_add2 (ctx, - eh, - handle->post_ctx.headers, - &handle_post_token_families_finished, - handle); - GNUNET_assert (NULL != handle->job); - } - return handle; + json_decref (req_obj); + ptfh->job = GNUNET_CURL_job_add2 (ptfh->ctx, + eh, + ptfh->post_ctx.headers, + &handle_post_tokenfamilies_finished, + ptfh); + if (NULL == ptfh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_token_families_post_cancel ( - struct TALER_MERCHANT_TokenFamiliesPostHandle *pph) +TALER_MERCHANT_post_private_tokenfamilies_cancel ( + struct TALER_MERCHANT_PostPrivateTokenfamiliesHandle *ptfh) { - if (NULL != pph->job) + if (NULL != ptfh->job) { - GNUNET_CURL_job_cancel (pph->job); - pph->job = NULL; + GNUNET_CURL_job_cancel (ptfh->job); + ptfh->job = NULL; } - TALER_curl_easy_post_finished (&pph->post_ctx); - GNUNET_free (pph->url); - GNUNET_free (pph); + TALER_curl_easy_post_finished (&ptfh->post_ctx); + json_decref (ptfh->description_i18n); + json_decref (ptfh->extra_data); + GNUNET_free (ptfh->slug); + GNUNET_free (ptfh->name); + GNUNET_free (ptfh->description); + GNUNET_free (ptfh->kind); + GNUNET_free (ptfh->url); + GNUNET_free (ptfh->base_url); + GNUNET_free (ptfh); } + + +/* end of merchant_api_post-private-tokenfamilies-new.c */ diff --git a/src/lib/merchant_api_post-private-transfers-new.c b/src/lib/merchant_api_post-private-transfers-new.c @@ -1,286 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-transfers-new.c - * @brief Implementation of the POST /private/transfers request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-transfers-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/transfers operation. - */ -struct TALER_MERCHANT_PostPrivateTransfersHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateTransfersCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Amount credited in this transfer. - */ - struct TALER_Amount credit_amount; - - /** - * Wire transfer identifier. - */ - struct TALER_WireTransferIdentifierRawP wtid; - - /** - * Payto URI of the merchant account. - */ - struct TALER_FullPayto payto_uri; - - /** - * Base URL of the exchange. - */ - char *exchange_url; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/transfers request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateTransfersHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_transfers_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateTransfersResponse ptr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppth->job = NULL; - switch (response_code) - { - case 0: - ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_UNAUTHORIZED: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Did not find any data\n"); - 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); - break; - case MHD_HTTP_BAD_GATEWAY: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - { - uint32_t ehc; - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_ec ("exchange_code", - &ptr.details.bad_gateway.exchange_ec), - GNUNET_JSON_spec_uint32 ("exchange_http_status", - &ehc), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json, - ispec, - NULL, NULL)) - { - GNUNET_break_op (0); - ptr.details.bad_gateway.exchange_http_status = 0; - ptr.details.bad_gateway.exchange_ec = TALER_EC_NONE; - break; - } - else - { - ptr.details.bad_gateway.exchange_http_status - = (unsigned int) ehc; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Exchange returned %u/%u\n", - (unsigned int) ptr.details.bad_gateway.exchange_ec, - (unsigned int) ehc); - } - } - break; - case MHD_HTTP_GATEWAY_TIMEOUT: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - GNUNET_break_op (0); - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &ptr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) ptr.hr.http_status, - (int) ptr.hr.ec); - break; - } - ppth->cb (ppth->cb_cls, - &ptr); - TALER_MERCHANT_post_private_transfers_cancel (ppth); -} - - -struct TALER_MERCHANT_PostPrivateTransfersHandle * -TALER_MERCHANT_post_private_transfers_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct TALER_Amount *credit_amount, - const struct TALER_WireTransferIdentifierRawP *wtid, - struct TALER_FullPayto payto_uri, - const char *exchange_url) -{ - struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth; - - ppth = GNUNET_new (struct TALER_MERCHANT_PostPrivateTransfersHandle); - ppth->ctx = ctx; - ppth->base_url = GNUNET_strdup (url); - ppth->credit_amount = *credit_amount; - ppth->wtid = *wtid; - ppth->payto_uri.full_payto = GNUNET_strdup (payto_uri.full_payto); - ppth->exchange_url = GNUNET_strdup (exchange_url); - return ppth; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_transfers_start ( - struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth, - TALER_MERCHANT_PostPrivateTransfersCallback cb, - TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppth->cb = cb; - ppth->cb_cls = cb_cls; - ppth->url = TALER_url_join (ppth->base_url, - "private/transfers", - NULL); - if (NULL == ppth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("credit_amount", - &ppth->credit_amount), - GNUNET_JSON_pack_data_auto ("wtid", - &ppth->wtid), - TALER_JSON_pack_full_payto ("payto_uri", - ppth->payto_uri), - GNUNET_JSON_pack_string ("exchange_url", - ppth->exchange_url)); - eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppth->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppth->job = GNUNET_CURL_job_add2 (ppth->ctx, - eh, - ppth->post_ctx.headers, - &handle_post_transfers_finished, - ppth); - if (NULL == ppth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_transfers_cancel ( - struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth) -{ - if (NULL != ppth->job) - { - GNUNET_CURL_job_cancel (ppth->job); - ppth->job = NULL; - } - TALER_curl_easy_post_finished (&ppth->post_ctx); - GNUNET_free (ppth->payto_uri.full_payto); - GNUNET_free (ppth->exchange_url); - GNUNET_free (ppth->url); - GNUNET_free (ppth->base_url); - GNUNET_free (ppth); -} - - -/* end of merchant_api_post-private-transfers-new.c */ diff --git a/src/lib/merchant_api_post-private-transfers.c b/src/lib/merchant_api_post-private-transfers.c @@ -1,23 +1,24 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1, + or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + TALER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see - <http://www.gnu.org/licenses/> + You should have received a copy of the GNU Lesser General + Public License along with TALER; see the file COPYING.LGPL. + If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-transfers.c - * @brief Implementation of the POST /transfers request of the merchant's HTTP API - * @author Marcello Stanisci + * @file merchant_api_post-private-transfers-new.c + * @brief Implementation of the POST /private/transfers request * @author Christian Grothoff */ #include "taler/platform.h" @@ -25,21 +26,26 @@ #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-transfers.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" -#include <taler/taler_curl_lib.h> #include <taler/taler_json_lib.h> +#include <taler/taler_curl_lib.h> /** - * @brief A handle for POSTing transfer data. + * Handle for a POST /private/transfers operation. */ -struct TALER_MERCHANT_PostTransfersHandle +struct TALER_MERCHANT_PostPrivateTransfersHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -51,12 +57,12 @@ struct TALER_MERCHANT_PostTransfersHandle /** * Function to call with the result. */ - TALER_MERCHANT_PostTransfersCallback cb; + TALER_MERCHANT_PostPrivateTransfersCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -68,14 +74,33 @@ struct TALER_MERCHANT_PostTransfersHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Amount credited in this transfer. + */ + struct TALER_Amount credit_amount; + + /** + * Wire transfer identifier. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * Payto URI of the merchant account. + */ + struct TALER_FullPayto payto_uri; + + /** + * Base URL of the exchange. + */ + char *exchange_url; }; /** * Function called when we're done processing the - * HTTP POST /transfers request. + * HTTP POST /private/transfers request. * - * @param cls the `struct TALER_MERCHANT_PostTransfersHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateTransfersHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -84,13 +109,14 @@ handle_post_transfers_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_PostTransfersHandle *pth = cls; - struct TALER_MERCHANT_PostTransfersResponse ptr = { - .hr.reply = response, - .hr.http_status = (unsigned int) response_code + struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth = cls; + const json_t *json = response; + struct TALER_MERCHANT_PostPrivateTransfersResponse ptr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - pth->job = NULL; + ppth->job = NULL; switch (response_code) { case 0: @@ -99,29 +125,22 @@ handle_post_transfers_finished (void *cls, case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: - ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply); - ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply); - /* Nothing really to verify, merchant says we need to authenticate. */ + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the application */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Did not find any data\n"); - ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply); - ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply); + 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: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ - ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply); - ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply); + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_BAD_GATEWAY: - /* Exchange had an issue; we should retry, but this API - leaves this to the application */ - ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply); - ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply); + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); { uint32_t ehc; struct GNUNET_JSON_Specification ispec[] = { @@ -133,7 +152,7 @@ handle_post_transfers_finished (void *cls, }; if (GNUNET_OK != - GNUNET_JSON_parse (ptr.hr.reply, + GNUNET_JSON_parse (json, ispec, NULL, NULL)) { @@ -154,15 +173,12 @@ handle_post_transfers_finished (void *cls, } break; case MHD_HTTP_GATEWAY_TIMEOUT: - /* Server had an internal issue; we should retry, but this API - leaves this to the application */ - ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply); - ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply); + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); break; default: - /* unexpected response code */ GNUNET_break_op (0); - TALER_MERCHANT_parse_error_details_ (ptr.hr.reply, + TALER_MERCHANT_parse_error_details_ (json, response_code, &ptr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -171,86 +187,100 @@ handle_post_transfers_finished (void *cls, (int) ptr.hr.ec); break; } - pth->cb (pth->cb_cls, - &ptr); - TALER_MERCHANT_transfers_post_cancel (pth); + ppth->cb (ppth->cb_cls, + &ptr); + TALER_MERCHANT_post_private_transfers_cancel (ppth); } -struct TALER_MERCHANT_PostTransfersHandle * -TALER_MERCHANT_transfers_post ( +struct TALER_MERCHANT_PostPrivateTransfersHandle * +TALER_MERCHANT_post_private_transfers_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const struct TALER_Amount *credit_amount, const struct TALER_WireTransferIdentifierRawP *wtid, struct TALER_FullPayto payto_uri, - const char *exchange_url, - TALER_MERCHANT_PostTransfersCallback cb, - void *cb_cls) + const char *exchange_url) { - struct TALER_MERCHANT_PostTransfersHandle *pth; + struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth; + + ppth = GNUNET_new (struct TALER_MERCHANT_PostPrivateTransfersHandle); + ppth->ctx = ctx; + ppth->base_url = GNUNET_strdup (url); + ppth->credit_amount = *credit_amount; + ppth->wtid = *wtid; + ppth->payto_uri.full_payto = GNUNET_strdup (payto_uri.full_payto); + ppth->exchange_url = GNUNET_strdup (exchange_url); + return ppth; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_transfers_start ( + struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth, + TALER_MERCHANT_PostPrivateTransfersCallback cb, + TALER_MERCHANT_POST_PRIVATE_TRANSFERS_RESULT_CLOSURE *cb_cls) +{ + json_t *req_obj; CURL *eh; - json_t *req; - pth = GNUNET_new (struct TALER_MERCHANT_PostTransfersHandle); - pth->ctx = ctx; - pth->cb = cb; - pth->cb_cls = cb_cls; - pth->url = TALER_url_join (backend_url, - "private/transfers", - NULL); - if (NULL == pth->url) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - GNUNET_free (pth); - return NULL; - } - req = GNUNET_JSON_PACK ( + ppth->cb = cb; + ppth->cb_cls = cb_cls; + ppth->url = TALER_url_join (ppth->base_url, + "private/transfers", + NULL); + if (NULL == ppth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + req_obj = GNUNET_JSON_PACK ( TALER_JSON_pack_amount ("credit_amount", - credit_amount), + &ppth->credit_amount), GNUNET_JSON_pack_data_auto ("wtid", - wtid), + &ppth->wtid), TALER_JSON_pack_full_payto ("payto_uri", - payto_uri), + ppth->payto_uri), GNUNET_JSON_pack_string ("exchange_url", - exchange_url)); - eh = TALER_MERCHANT_curl_easy_get_ (pth->url); - if (GNUNET_OK != - TALER_curl_easy_post (&pth->post_ctx, - eh, - req)) + ppth->exchange_url)); + eh = TALER_MERCHANT_curl_easy_get_ (ppth->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppth->post_ctx, + eh, + req_obj)) ) { GNUNET_break (0); - curl_easy_cleanup (eh); - json_decref (req); - GNUNET_free (pth->url); - GNUNET_free (pth); - return NULL; + json_decref (req_obj); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - json_decref (req); - pth->job = GNUNET_CURL_job_add2 (ctx, - eh, - pth->post_ctx.headers, - &handle_post_transfers_finished, - pth); - return pth; + json_decref (req_obj); + ppth->job = GNUNET_CURL_job_add2 (ppth->ctx, + eh, + ppth->post_ctx.headers, + &handle_post_transfers_finished, + ppth); + if (NULL == ppth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_transfers_post_cancel ( - struct TALER_MERCHANT_PostTransfersHandle *pth) +TALER_MERCHANT_post_private_transfers_cancel ( + struct TALER_MERCHANT_PostPrivateTransfersHandle *ppth) { - if (NULL != pth->job) + if (NULL != ppth->job) { - GNUNET_CURL_job_cancel (pth->job); - pth->job = NULL; + GNUNET_CURL_job_cancel (ppth->job); + ppth->job = NULL; } - GNUNET_free (pth->url); - TALER_curl_easy_post_finished (&pth->post_ctx); - GNUNET_free (pth); + TALER_curl_easy_post_finished (&ppth->post_ctx); + GNUNET_free (ppth->payto_uri.full_payto); + GNUNET_free (ppth->exchange_url); + GNUNET_free (ppth->url); + GNUNET_free (ppth->base_url); + GNUNET_free (ppth); } -/* end of merchant_api_post_transfers.c */ +/* end of merchant_api_post-private-transfers-new.c */ diff --git a/src/lib/merchant_api_post-private-units-new.c b/src/lib/merchant_api_post-private-units-new.c @@ -1,312 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2025-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-units-new.c - * @brief Implementation of the POST /private/units request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-units-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/units operation. - */ -struct TALER_MERCHANT_PostPrivateUnitsHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateUnitsCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Unit identifier. - */ - char *unit_id; - - /** - * Long human-readable name. - */ - char *unit_name_long; - - /** - * Short symbol for the unit. - */ - char *unit_name_short; - - /** - * Whether fractional quantities are allowed. - */ - bool unit_allow_fraction; - - /** - * Precision level for fractional quantities. - */ - uint32_t unit_precision_level; - - /** - * Whether the unit is active. - */ - bool unit_active; - - /** - * Optional internationalized long names (JSON). - */ - json_t *unit_name_long_i18n; - - /** - * Optional internationalized short names (JSON). - */ - json_t *unit_name_short_i18n; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/units request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateUnitsHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_units_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateUnitsResponse pur = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppuh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/units completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - pur.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - case MHD_HTTP_UNAUTHORIZED: - case MHD_HTTP_FORBIDDEN: - case MHD_HTTP_NOT_FOUND: - case MHD_HTTP_CONFLICT: - case MHD_HTTP_INTERNAL_SERVER_ERROR: - pur.hr.ec = TALER_JSON_get_error_code (json); - pur.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &pur.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) pur.hr.ec); - GNUNET_break_op (0); - break; - } - ppuh->cb (ppuh->cb_cls, - &pur); - TALER_MERCHANT_post_private_units_cancel (ppuh); -} - - -struct TALER_MERCHANT_PostPrivateUnitsHandle * -TALER_MERCHANT_post_private_units_create ( - struct GNUNET_CURL_Context *ctx, - 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) -{ - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh; - - ppuh = GNUNET_new (struct TALER_MERCHANT_PostPrivateUnitsHandle); - ppuh->ctx = ctx; - ppuh->base_url = GNUNET_strdup (url); - 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; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_private_units_set_options_ ( - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, - unsigned int num_options, - const struct TALER_MERCHANT_PostPrivateUnitsOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N: - ppuh->unit_name_long_i18n - = json_incref ((json_t *) options[i].details.unit_name_long_i18n); - break; - case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N: - ppuh->unit_name_short_i18n - = json_incref ((json_t *) options[i].details.unit_name_short_i18n); - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_private_units_start ( - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, - TALER_MERCHANT_PostPrivateUnitsCallback cb, - TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppuh->cb = cb; - ppuh->cb_cls = cb_cls; - ppuh->url = TALER_url_join (ppuh->base_url, - "private/units", - NULL); - if (NULL == ppuh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("unit", - ppuh->unit_id), - GNUNET_JSON_pack_string ("unit_name_long", - ppuh->unit_name_long), - GNUNET_JSON_pack_string ("unit_name_short", - ppuh->unit_name_short), - GNUNET_JSON_pack_bool ("unit_allow_fraction", - ppuh->unit_allow_fraction), - GNUNET_JSON_pack_uint64 ("unit_precision_level", - (uint64_t) ppuh->unit_precision_level), - GNUNET_JSON_pack_bool ("unit_active", - ppuh->unit_active), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("unit_name_long_i18n", - ppuh->unit_name_long_i18n)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("unit_name_short_i18n", - ppuh->unit_name_short_i18n))); - eh = TALER_MERCHANT_curl_easy_get_ (ppuh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppuh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppuh->job = GNUNET_CURL_job_add2 (ppuh->ctx, - eh, - ppuh->post_ctx.headers, - &handle_post_units_finished, - ppuh); - if (NULL == ppuh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_units_cancel ( - struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh) -{ - if (NULL != ppuh->job) - { - GNUNET_CURL_job_cancel (ppuh->job); - ppuh->job = NULL; - } - TALER_curl_easy_post_finished (&ppuh->post_ctx); - json_decref (ppuh->unit_name_long_i18n); - json_decref (ppuh->unit_name_short_i18n); - GNUNET_free (ppuh->unit_id); - GNUNET_free (ppuh->unit_name_long); - GNUNET_free (ppuh->unit_name_short); - GNUNET_free (ppuh->url); - GNUNET_free (ppuh->base_url); - GNUNET_free (ppuh); -} - - -/* end of merchant_api_post-private-units-new.c */ diff --git a/src/lib/merchant_api_post-private-units.c b/src/lib/merchant_api_post-private-units.c @@ -1,29 +1,33 @@ /* This file is part of TALER - Copyright (C) 2025 Taler Systems SA + Copyright (C) 2025-2026 Taler Systems SA - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free - Software Foundation; either version 2.1, or (at your option) any later version. + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1, + or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + TALER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING.LGPL. If not, see <http://www.gnu.org/licenses/> + You should have received a copy of the GNU Lesser General + Public License along with TALER; see the file COPYING.LGPL. + If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-units.c - * @brief Implementation of POST /private/units - * @author Bohdan Potuzhnyi + * @file merchant_api_post-private-units-new.c + * @brief Implementation of the POST /private/units request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> -#include <microhttpd.h> +#include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-units.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -33,65 +37,114 @@ /** * Handle for a POST /private/units operation. */ -struct TALER_MERCHANT_UnitsPostHandle +struct TALER_MERCHANT_PostPrivateUnitsHandle { /** - * Fully qualified request URL. + * Base URL of the merchant backend. + */ + char *base_url; + + /** + * The full URL for this request. */ char *url; /** - * CURL job handle. + * Handle for the request. */ struct GNUNET_CURL_Job *job; /** - * Callback to invoke with the result. + * Function to call with the result. */ - TALER_MERCHANT_UnitsPostCallback cb; + TALER_MERCHANT_PostPrivateUnitsCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls; /** - * Execution context. + * Reference to the execution context. */ struct GNUNET_CURL_Context *ctx; /** - * Helper keeping POST body and headers alive. + * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Unit identifier. + */ + char *unit_id; + + /** + * Long human-readable name. + */ + char *unit_name_long; + + /** + * Short symbol for the unit. + */ + char *unit_name_short; + + /** + * Whether fractional quantities are allowed. + */ + bool unit_allow_fraction; + + /** + * Precision level for fractional quantities. + */ + uint32_t unit_precision_level; + + /** + * Whether the unit is active. + */ + bool unit_active; + + /** + * Optional internationalized long names (JSON). + */ + json_t *unit_name_long_i18n; + + /** + * Optional internationalized short names (JSON). + */ + json_t *unit_name_short_i18n; }; /** - * Called when the HTTP transfer finishes. + * Function called when we're done processing the + * HTTP POST /private/units request. * - * @param cls operation handle - * @param response_code HTTP status (0 on network / parsing failures) - * @param response parsed JSON reply (NULL if unavailable) + * @param cls the `struct TALER_MERCHANT_PostPrivateUnitsHandle` + * @param response_code HTTP response code, 0 on error + * @param response response body, NULL if not in JSON */ static void handle_post_units_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_UnitsPostHandle *uph = cls; + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateUnitsResponse pur = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - uph->job = NULL; + ppuh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/units completed with status %u\n", + "POST /private/units completed with response code %u\n", (unsigned int) response_code); switch (response_code) { + case 0: + pur.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: @@ -100,119 +153,160 @@ handle_post_units_finished (void *cls, case MHD_HTTP_NOT_FOUND: case MHD_HTTP_CONFLICT: case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - break; - case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + pur.hr.ec = TALER_JSON_get_error_code (json); + pur.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); + &pur.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response %u/%d for POST /private/units\n", + "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) pur.hr.ec); GNUNET_break_op (0); break; } - uph->cb (uph->cb_cls, - &hr); - TALER_MERCHANT_units_post_cancel (uph); + ppuh->cb (ppuh->cb_cls, + &pur); + TALER_MERCHANT_post_private_units_cancel (ppuh); +} + + +struct TALER_MERCHANT_PostPrivateUnitsHandle * +TALER_MERCHANT_post_private_units_create ( + struct GNUNET_CURL_Context *ctx, + 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) +{ + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh; + + ppuh = GNUNET_new (struct TALER_MERCHANT_PostPrivateUnitsHandle); + ppuh->ctx = ctx; + ppuh->base_url = GNUNET_strdup (url); + 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; } -struct TALER_MERCHANT_UnitsPostHandle * -TALER_MERCHANT_units_post (struct GNUNET_CURL_Context *ctx, - const char *backend_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 json_t *unit_name_long_i18n, - const json_t *unit_name_short_i18n, - TALER_MERCHANT_UnitsPostCallback cb, - void *cb_cls) +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_private_units_set_options_ ( + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, + unsigned int num_options, + const struct TALER_MERCHANT_PostPrivateUnitsOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_LONG_I18N: + ppuh->unit_name_long_i18n + = json_incref ((json_t *) options[i].details.unit_name_long_i18n); + break; + case TALER_MERCHANT_POST_PRIVATE_UNITS_OPTION_UNIT_NAME_SHORT_I18N: + ppuh->unit_name_short_i18n + = json_incref ((json_t *) options[i].details.unit_name_short_i18n); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_private_units_start ( + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh, + TALER_MERCHANT_PostPrivateUnitsCallback cb, + TALER_MERCHANT_POST_PRIVATE_UNITS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_UnitsPostHandle *uph; json_t *req_obj; + CURL *eh; + ppuh->cb = cb; + ppuh->cb_cls = cb_cls; + ppuh->url = TALER_url_join (ppuh->base_url, + "private/units", + NULL); + if (NULL == ppuh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("unit", - unit_id), + ppuh->unit_id), GNUNET_JSON_pack_string ("unit_name_long", - unit_name_long), + ppuh->unit_name_long), GNUNET_JSON_pack_string ("unit_name_short", - unit_name_short), + ppuh->unit_name_short), GNUNET_JSON_pack_bool ("unit_allow_fraction", - unit_allow_fraction), + ppuh->unit_allow_fraction), GNUNET_JSON_pack_uint64 ("unit_precision_level", - (uint64_t) unit_precision_level), + (uint64_t) ppuh->unit_precision_level), GNUNET_JSON_pack_bool ("unit_active", - unit_active), + ppuh->unit_active), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("unit_name_long_i18n", - (json_t *) unit_name_long_i18n)), + ppuh->unit_name_long_i18n)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("unit_name_short_i18n", - (json_t *) unit_name_short_i18n))); - uph = GNUNET_new (struct TALER_MERCHANT_UnitsPostHandle); - uph->ctx = ctx; - uph->cb = cb; - uph->cb_cls = cb_cls; - uph->url = TALER_url_join (backend_url, - "private/units", - NULL); - if (NULL == uph->url) + ppuh->unit_name_short_i18n))); + eh = TALER_MERCHANT_curl_easy_get_ (ppuh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppuh->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to build /private/units URL\n"); + GNUNET_break (0); json_decref (req_obj); - GNUNET_free (uph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (uph->url); - if (GNUNET_OK != - TALER_curl_easy_post (&uph->post_ctx, - eh, - req_obj)) - { - GNUNET_break (0); + if (NULL != eh) curl_easy_cleanup (eh); - json_decref (req_obj); - GNUNET_free (uph->url); - GNUNET_free (uph); - return NULL; - } - json_decref (req_obj); - uph->job = GNUNET_CURL_job_add2 (ctx, - eh, - uph->post_ctx.headers, - &handle_post_units_finished, - uph); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return uph; + json_decref (req_obj); + ppuh->job = GNUNET_CURL_job_add2 (ppuh->ctx, + eh, + ppuh->post_ctx.headers, + &handle_post_units_finished, + ppuh); + if (NULL == ppuh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_units_post_cancel (struct TALER_MERCHANT_UnitsPostHandle *uph) +TALER_MERCHANT_post_private_units_cancel ( + struct TALER_MERCHANT_PostPrivateUnitsHandle *ppuh) { - if (NULL != uph->job) + if (NULL != ppuh->job) { - GNUNET_CURL_job_cancel (uph->job); - uph->job = NULL; + GNUNET_CURL_job_cancel (ppuh->job); + ppuh->job = NULL; } - TALER_curl_easy_post_finished (&uph->post_ctx); - GNUNET_free (uph->url); - GNUNET_free (uph); + TALER_curl_easy_post_finished (&ppuh->post_ctx); + json_decref (ppuh->unit_name_long_i18n); + json_decref (ppuh->unit_name_short_i18n); + GNUNET_free (ppuh->unit_id); + GNUNET_free (ppuh->unit_name_long); + GNUNET_free (ppuh->unit_name_short); + GNUNET_free (ppuh->url); + GNUNET_free (ppuh->base_url); + GNUNET_free (ppuh); } -/* end of merchant_api_post_units.c */ +/* end of merchant_api_post-private-units-new.c */ diff --git a/src/lib/merchant_api_post-private-webhooks-new.c b/src/lib/merchant_api_post-private-webhooks-new.c @@ -1,283 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-private-webhooks-new.c - * @brief Implementation of the POST /private/webhooks request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-private-webhooks-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /private/webhooks operation. - */ -struct TALER_MERCHANT_PostPrivateWebhooksHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostPrivateWebhooksCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Webhook identifier. - */ - char *webhook_id; - - /** - * Event type that triggers this webhook. - */ - char *event_type; - - /** - * URL to send notifications to. - */ - char *notification_url; - - /** - * HTTP method to use for notifications. - */ - char *http_method; - - /** - * Template for HTTP request headers. - */ - char *header_template; - - /** - * Template for the HTTP request body. - */ - char *body_template; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /private/webhooks request. - * - * @param cls the `struct TALER_MERCHANT_PostPrivateWebhooksHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_webhooks_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostPrivateWebhooksResponse wpr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - - ppwh->job = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /private/webhooks completed with response code %u\n", - (unsigned int) response_code); - switch (response_code) - { - case 0: - wpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_BAD_REQUEST: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_CONFLICT: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_INTERNAL_SERVER_ERROR: - wpr.hr.ec = TALER_JSON_get_error_code (json); - wpr.hr.hint = TALER_JSON_get_error_hint (json); - break; - default: - TALER_MERCHANT_parse_error_details_ (json, - response_code, - &wpr.hr); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) wpr.hr.ec); - GNUNET_break_op (0); - break; - } - ppwh->cb (ppwh->cb_cls, - &wpr); - TALER_MERCHANT_post_private_webhooks_cancel (ppwh); -} - - -struct TALER_MERCHANT_PostPrivateWebhooksHandle * -TALER_MERCHANT_post_private_webhooks_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *webhook_id, - const char *event_type, - const char *notification_url, - const char *http_method, - const char *header_template, - const char *body_template) -{ - struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh; - - ppwh = GNUNET_new (struct TALER_MERCHANT_PostPrivateWebhooksHandle); - ppwh->ctx = ctx; - ppwh->base_url = GNUNET_strdup (url); - ppwh->webhook_id = GNUNET_strdup (webhook_id); - 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 TALER_ErrorCode -TALER_MERCHANT_post_private_webhooks_start ( - struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, - TALER_MERCHANT_PostPrivateWebhooksCallback cb, - TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - ppwh->cb = cb; - ppwh->cb_cls = cb_cls; - ppwh->url = TALER_url_join (ppwh->base_url, - "private/webhooks", - NULL); - if (NULL == ppwh->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("webhook_id", - ppwh->webhook_id), - GNUNET_JSON_pack_string ("event_type", - ppwh->event_type), - GNUNET_JSON_pack_string ("url", - 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)); - eh = TALER_MERCHANT_curl_easy_get_ (ppwh->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&ppwh->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - ppwh->job = GNUNET_CURL_job_add2 (ppwh->ctx, - eh, - ppwh->post_ctx.headers, - &handle_post_webhooks_finished, - ppwh); - if (NULL == ppwh->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_private_webhooks_cancel ( - struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh) -{ - if (NULL != ppwh->job) - { - GNUNET_CURL_job_cancel (ppwh->job); - ppwh->job = NULL; - } - TALER_curl_easy_post_finished (&ppwh->post_ctx); - GNUNET_free (ppwh->webhook_id); - 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); -} - - -/* end of merchant_api_post-private-webhooks-new.c */ diff --git a/src/lib/merchant_api_post-private-webhooks.c b/src/lib/merchant_api_post-private-webhooks.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,17 +17,17 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-private-webhooks.c - * @brief Implementation of the POST /webhooks request - * of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_post-private-webhooks-new.c + * @brief Implementation of the POST /private/webhooks request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-private-webhooks.h> #include "merchant_api_curl_defaults.h" #include "merchant_api_common.h" #include <taler/taler_json_lib.h> @@ -35,13 +35,17 @@ /** - * Handle for a POST /webhooks/$ID operation. + * Handle for a POST /private/webhooks operation. */ -struct TALER_MERCHANT_WebhooksPostHandle +struct TALER_MERCHANT_PostPrivateWebhooksHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_WebhooksPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_WebhooksPostCallback cb; + TALER_MERCHANT_PostPrivateWebhooksCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -70,14 +74,43 @@ struct TALER_MERCHANT_WebhooksPostHandle */ struct TALER_CURL_PostContext post_ctx; + /** + * Webhook identifier. + */ + char *webhook_id; + + /** + * Event type that triggers this webhook. + */ + char *event_type; + + /** + * URL to send notifications to. + */ + char *notification_url; + + /** + * HTTP method to use for notifications. + */ + char *http_method; + + /** + * Template for HTTP request headers. + */ + char *header_template; + + /** + * Template for the HTTP request body. + */ + char *body_template; }; /** * Function called when we're done processing the - * HTTP POST /webhooks request. + * HTTP POST /private/webhooks request. * - * @param cls the `struct TALER_MERCHANT_WebhooksPostHandle` + * @param cls the `struct TALER_MERCHANT_PostPrivateWebhooksHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ @@ -86,155 +119,165 @@ handle_post_webhooks_finished (void *cls, long response_code, const void *response) { - struct TALER_MERCHANT_WebhooksPostHandle *wph = cls; + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_PostPrivateWebhooksResponse wpr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; - wph->job = NULL; + ppwh->job = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "POST /webhooks completed with response code %u\n", + "POST /private/webhooks completed with response code %u\n", (unsigned int) response_code); switch (response_code) { case 0: - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + wpr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_BAD_REQUEST: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* This should never happen, either us - * or the merchant is buggy (or API version conflict); - * just pass JSON reply to the application */ + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we need to authenticate. */ + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_FORBIDDEN: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, merchant says we tried to abort the payment - * after it was successful. We should pass the JSON reply to the - * application */ + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_NOT_FOUND: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Nothing really to verify, this should never - happen, we should pass the JSON reply to the - application */ + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; case MHD_HTTP_INTERNAL_SERVER_ERROR: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - /* Server had an internal issue; we should retry, - but this API leaves this to the application */ + wpr.hr.ec = TALER_JSON_get_error_code (json); + wpr.hr.hint = TALER_JSON_get_error_hint (json); break; default: TALER_MERCHANT_parse_error_details_ (json, response_code, - &hr); - /* unexpected response code */ + &wpr.hr); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) wpr.hr.ec); GNUNET_break_op (0); break; } - wph->cb (wph->cb_cls, - &hr); - TALER_MERCHANT_webhooks_post_cancel (wph); + ppwh->cb (ppwh->cb_cls, + &wpr); + TALER_MERCHANT_post_private_webhooks_cancel (ppwh); } -struct TALER_MERCHANT_WebhooksPostHandle * -TALER_MERCHANT_webhooks_post ( +struct TALER_MERCHANT_PostPrivateWebhooksHandle * +TALER_MERCHANT_post_private_webhooks_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, + const char *url, const char *webhook_id, const char *event_type, - const char *url, + const char *notification_url, const char *http_method, const char *header_template, - const char *body_template, - TALER_MERCHANT_WebhooksPostCallback cb, - void *cb_cls) + const char *body_template) +{ + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh; + + ppwh = GNUNET_new (struct TALER_MERCHANT_PostPrivateWebhooksHandle); + ppwh->ctx = ctx; + ppwh->base_url = GNUNET_strdup (url); + ppwh->webhook_id = GNUNET_strdup (webhook_id); + 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 TALER_ErrorCode +TALER_MERCHANT_post_private_webhooks_start ( + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh, + TALER_MERCHANT_PostPrivateWebhooksCallback cb, + TALER_MERCHANT_POST_PRIVATE_WEBHOOKS_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_WebhooksPostHandle *wph; json_t *req_obj; + CURL *eh; + ppwh->cb = cb; + ppwh->cb_cls = cb_cls; + ppwh->url = TALER_url_join (ppwh->base_url, + "private/webhooks", + NULL); + if (NULL == ppwh->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; req_obj = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("webhook_id", - webhook_id), + ppwh->webhook_id), GNUNET_JSON_pack_string ("event_type", - event_type), + ppwh->event_type), GNUNET_JSON_pack_string ("url", - url), + ppwh->notification_url), GNUNET_JSON_pack_string ("http_method", - http_method), + ppwh->http_method), GNUNET_JSON_pack_string ("header_template", - header_template), + ppwh->header_template), GNUNET_JSON_pack_string ("body_template", - body_template)); - wph = GNUNET_new (struct TALER_MERCHANT_WebhooksPostHandle); - wph->ctx = ctx; - wph->cb = cb; - wph->cb_cls = cb_cls; - wph->url = TALER_url_join (backend_url, - "private/webhooks", - NULL); - if (NULL == wph->url) + ppwh->body_template)); + eh = TALER_MERCHANT_curl_easy_get_ (ppwh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&ppwh->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (wph); - return NULL; - } - { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (wph->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&wph->post_ctx, - eh, - req_obj)); + GNUNET_break (0); json_decref (req_obj); - wph->job = GNUNET_CURL_job_add2 (ctx, - eh, - wph->post_ctx.headers, - &handle_post_webhooks_finished, - wph); - GNUNET_assert (NULL != wph->job); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return wph; + json_decref (req_obj); + ppwh->job = GNUNET_CURL_job_add2 (ppwh->ctx, + eh, + ppwh->post_ctx.headers, + &handle_post_webhooks_finished, + ppwh); + if (NULL == ppwh->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_webhooks_post_cancel ( - struct TALER_MERCHANT_WebhooksPostHandle *wph) +TALER_MERCHANT_post_private_webhooks_cancel ( + struct TALER_MERCHANT_PostPrivateWebhooksHandle *ppwh) { - if (NULL != wph->job) + if (NULL != ppwh->job) { - GNUNET_CURL_job_cancel (wph->job); - wph->job = NULL; + GNUNET_CURL_job_cancel (ppwh->job); + ppwh->job = NULL; } - TALER_curl_easy_post_finished (&wph->post_ctx); - GNUNET_free (wph->url); - GNUNET_free (wph); + TALER_curl_easy_post_finished (&ppwh->post_ctx); + GNUNET_free (ppwh->webhook_id); + 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); } -/* end of merchant_api_post_webhooks.c */ +/* end of merchant_api_post-private-webhooks-new.c */ diff --git a/src/lib/merchant_api_post-templates-TEMPLATE_ID-new.c b/src/lib/merchant_api_post-templates-TEMPLATE_ID-new.c @@ -1,330 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2022-2026 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1, - or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with TALER; see the file COPYING.LGPL. - If not, see <http://www.gnu.org/licenses/> -*/ -/** - * @file merchant_api_post-templates-TEMPLATE_ID-new.c - * @brief Implementation of the POST /templates/$TEMPLATE_ID request - * @author Christian Grothoff - */ -#include "taler/platform.h" -#include <curl/curl.h> -#include <jansson.h> -#include <microhttpd.h> /* just for HTTP status codes */ -#include <gnunet/gnunet_util_lib.h> -#include <gnunet/gnunet_curl_lib.h> -#include <taler/taler-merchant/post-templates-TEMPLATE_ID-new.h> -#include "merchant_api_curl_defaults.h" -#include "merchant_api_common.h" -#include <taler/taler_json_lib.h> -#include <taler/taler_curl_lib.h> - - -/** - * Handle for a POST /templates/$TEMPLATE_ID operation. - */ -struct TALER_MERCHANT_PostTemplatesHandle -{ - /** - * Base URL of the merchant backend. - */ - char *base_url; - - /** - * The full URL for this request. - */ - char *url; - - /** - * Handle for the request. - */ - struct GNUNET_CURL_Job *job; - - /** - * Function to call with the result. - */ - TALER_MERCHANT_PostTemplatesCallback cb; - - /** - * Closure for @a cb. - */ - TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cb_cls; - - /** - * Reference to the execution context. - */ - struct GNUNET_CURL_Context *ctx; - - /** - * Minor context that holds body and headers. - */ - struct TALER_CURL_PostContext post_ctx; - - /** - * Template identifier. - */ - char *template_id; - - /** - * Optional summary string. - */ - const char *summary; - - /** - * Optional amount. - */ - const struct TALER_Amount *amount; - - /** - * Optional detailed contract customization (JSON). - */ - const json_t *details; -}; - - -/** - * Function called when we're done processing the - * HTTP POST /templates/$TEMPLATE_ID request. - * - * @param cls the `struct TALER_MERCHANT_PostTemplatesHandle` - * @param response_code HTTP response code, 0 on error - * @param response response body, NULL if not in JSON - */ -static void -handle_post_templates_finished (void *cls, - long response_code, - const void *response) -{ - struct TALER_MERCHANT_PostTemplatesHandle *pth = cls; - const json_t *json = response; - struct TALER_MERCHANT_PostTemplatesResponse ptr = { - .hr.http_status = (unsigned int) response_code, - .hr.reply = json - }; - struct TALER_ClaimTokenP token; - - pth->job = NULL; - switch (response_code) - { - case 0: - ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - break; - case MHD_HTTP_OK: - { - bool no_token; - bool no_pay_deadline; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("order_id", - &ptr.details.ok.order_id), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_fixed_auto ("token", - &token), - &no_token), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_timestamp ("pay_deadline", - &ptr.details.ok.pay_deadline), - &no_pay_deadline), - 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; - } - if (! no_token) - ptr.details.ok.token = &token; - if (no_pay_deadline) - ptr.details.ok.pay_deadline = GNUNET_TIME_UNIT_ZERO_TS; - break; - } - case MHD_HTTP_BAD_REQUEST: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_UNAUTHORIZED: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_FORBIDDEN: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - break; - case MHD_HTTP_NOT_FOUND: - 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); - break; - default: - ptr.hr.ec = TALER_JSON_get_error_code (json); - ptr.hr.hint = TALER_JSON_get_error_hint (json); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u/%d\n", - (unsigned int) response_code, - (int) ptr.hr.ec); - GNUNET_break_op (0); - break; - } - pth->cb (pth->cb_cls, - &ptr); - TALER_MERCHANT_post_templates_cancel (pth); -} - - -struct TALER_MERCHANT_PostTemplatesHandle * -TALER_MERCHANT_post_templates_create ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const char *template_id) -{ - struct TALER_MERCHANT_PostTemplatesHandle *pth; - - pth = GNUNET_new (struct TALER_MERCHANT_PostTemplatesHandle); - pth->ctx = ctx; - pth->base_url = GNUNET_strdup (url); - pth->template_id = GNUNET_strdup (template_id); - return pth; -} - - -enum GNUNET_GenericReturnValue -TALER_MERCHANT_post_templates_set_options_ ( - struct TALER_MERCHANT_PostTemplatesHandle *pth, - unsigned int num_options, - const struct TALER_MERCHANT_PostTemplatesOptionValue *options) -{ - for (unsigned int i = 0; i < num_options; i++) - { - switch (options[i].option) - { - case TALER_MERCHANT_POST_TEMPLATES_OPTION_END: - return GNUNET_OK; - case TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY: - pth->summary = options[i].details.summary; - break; - case TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT: - pth->amount = options[i].details.amount; - break; - case TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS: - pth->details = options[i].details.details; - break; - default: - GNUNET_break (0); - return GNUNET_SYSERR; - } - } - return GNUNET_OK; -} - - -enum TALER_ErrorCode -TALER_MERCHANT_post_templates_start ( - struct TALER_MERCHANT_PostTemplatesHandle *pth, - TALER_MERCHANT_PostTemplatesCallback cb, - TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cb_cls) -{ - json_t *req_obj; - CURL *eh; - - pth->cb = cb; - pth->cb_cls = cb_cls; - { - char *path; - - GNUNET_asprintf (&path, - "templates/%s", - pth->template_id); - pth->url = TALER_url_join (pth->base_url, - path, - NULL); - GNUNET_free (path); - } - if (NULL == pth->url) - return TALER_EC_GENERIC_CONFIGURATION_INVALID; - if (NULL != pth->details) - { - /* If detailed contract customization is provided, send it directly. */ - req_obj = json_incref ((json_t *) pth->details); - } - else - { - /* Build fixed-order request with optional summary and amount. */ - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("template_type", - "fixed-order"), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("summary", - pth->summary)), - GNUNET_JSON_pack_allow_null ( - TALER_JSON_pack_amount ("amount", - pth->amount))); - } - eh = TALER_MERCHANT_curl_easy_get_ (pth->url); - if ( (NULL == eh) || - (GNUNET_OK != - TALER_curl_easy_post (&pth->post_ctx, - eh, - req_obj)) ) - { - GNUNET_break (0); - json_decref (req_obj); - if (NULL != eh) - curl_easy_cleanup (eh); - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - } - json_decref (req_obj); - pth->job = GNUNET_CURL_job_add2 (pth->ctx, - eh, - pth->post_ctx.headers, - &handle_post_templates_finished, - pth); - if (NULL == pth->job) - return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; - return TALER_EC_NONE; -} - - -void -TALER_MERCHANT_post_templates_cancel ( - struct TALER_MERCHANT_PostTemplatesHandle *pth) -{ - if (NULL != pth->job) - { - GNUNET_CURL_job_cancel (pth->job); - pth->job = NULL; - } - TALER_curl_easy_post_finished (&pth->post_ctx); - GNUNET_free (pth->template_id); - GNUNET_free (pth->url); - GNUNET_free (pth->base_url); - GNUNET_free (pth); -} - - -/* end of merchant_api_post-templates-TEMPLATE_ID-new.c */ diff --git a/src/lib/merchant_api_post-templates-TEMPLATE_ID.c b/src/lib/merchant_api_post-templates-TEMPLATE_ID.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022-2023 Taler Systems SA + Copyright (C) 2022-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -17,31 +17,35 @@ If not, see <http://www.gnu.org/licenses/> */ /** - * @file merchant_api_post-templates-TEMPLATE_ID.c - * @brief Implementation of the POST /using_templates request - * of the merchant's HTTP API - * @author Priscilla HUANG + * @file merchant_api_post-templates-TEMPLATE_ID-new.c + * @brief Implementation of the POST /templates/$TEMPLATE_ID request + * @author Christian Grothoff */ #include "taler/platform.h" #include <curl/curl.h> #include <jansson.h> #include <microhttpd.h> /* just for HTTP status codes */ #include <gnunet/gnunet_util_lib.h> -#include "taler/taler_merchant_service.h" -#include "merchant_api_common.h" +#include <gnunet/gnunet_curl_lib.h> +#include <taler/taler-merchant/post-templates-TEMPLATE_ID.h> #include "merchant_api_curl_defaults.h" +#include "merchant_api_common.h" #include <taler/taler_json_lib.h> #include <taler/taler_curl_lib.h> /** - * Handle for a POST /templates/$ID operation. + * Handle for a POST /templates/$TEMPLATE_ID operation. */ -struct TALER_MERCHANT_UsingTemplatesPostHandle +struct TALER_MERCHANT_PostTemplatesHandle { + /** + * Base URL of the merchant backend. + */ + char *base_url; /** - * The url for this request. + * The full URL for this request. */ char *url; @@ -53,12 +57,12 @@ struct TALER_MERCHANT_UsingTemplatesPostHandle /** * Function to call with the result. */ - TALER_MERCHANT_PostOrdersCallback cb; + TALER_MERCHANT_PostTemplatesCallback cb; /** * Closure for @a cb. */ - void *cb_cls; + TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cb_cls; /** * Reference to the execution context. @@ -69,165 +73,258 @@ struct TALER_MERCHANT_UsingTemplatesPostHandle * Minor context that holds body and headers. */ struct TALER_CURL_PostContext post_ctx; + + /** + * Template identifier. + */ + char *template_id; + + /** + * Optional summary string. + */ + const char *summary; + + /** + * Optional amount. + */ + const struct TALER_Amount *amount; + + /** + * Optional detailed contract customization (JSON). + */ + const json_t *details; }; + /** * Function called when we're done processing the - * HTTP POST /using-templates request. + * HTTP POST /templates/$TEMPLATE_ID request. * - * @param cls the `struct TALER_MERCHANT_UsingTemplatesPostHandle` + * @param cls the `struct TALER_MERCHANT_PostTemplatesHandle` * @param response_code HTTP response code, 0 on error * @param response response body, NULL if not in JSON */ static void -handle_post_using_templates_finished (void *cls, - long response_code, - const void *response) +handle_post_templates_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_UsingTemplatesPostHandle *utph = cls; + struct TALER_MERCHANT_PostTemplatesHandle *pth = cls; const json_t *json = response; + struct TALER_MERCHANT_PostTemplatesResponse ptr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json + }; + struct TALER_ClaimTokenP token; - utph->job = NULL; - TALER_MERCHANT_handle_order_creation_response_ (utph->cb, - utph->cb_cls, - response_code, - json); - TALER_MERCHANT_using_templates_post_cancel (utph); + pth->job = NULL; + switch (response_code) + { + case 0: + ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; + case MHD_HTTP_OK: + { + bool no_token; + bool no_pay_deadline; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("order_id", + &ptr.details.ok.order_id), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("token", + &token), + &no_token), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_timestamp ("pay_deadline", + &ptr.details.ok.pay_deadline), + &no_pay_deadline), + 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; + } + if (! no_token) + ptr.details.ok.token = &token; + if (no_pay_deadline) + ptr.details.ok.pay_deadline = GNUNET_TIME_UNIT_ZERO_TS; + break; + } + case MHD_HTTP_BAD_REQUEST: + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_UNAUTHORIZED: + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_FORBIDDEN: + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_NOT_FOUND: + 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); + break; + default: + ptr.hr.ec = TALER_JSON_get_error_code (json); + ptr.hr.hint = TALER_JSON_get_error_hint (json); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d\n", + (unsigned int) response_code, + (int) ptr.hr.ec); + GNUNET_break_op (0); + break; + } + pth->cb (pth->cb_cls, + &ptr); + TALER_MERCHANT_post_templates_cancel (pth); } -/** - * Helper to submit a POST /templates/$ID request. - * - * @param ctx the context - * @param backend_url HTTP base URL for the backend - * @param template_id identifier of the template to use - * @param req_obj JSON request body (consumed) - * @param cb function to call with the backend's result - * @param cb_cls closure for @a cb - * @return the request handle; NULL upon error - */ -static struct TALER_MERCHANT_UsingTemplatesPostHandle * -using_templates_post_internal ( +struct TALER_MERCHANT_PostTemplatesHandle * +TALER_MERCHANT_post_templates_create ( struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - json_t *req_obj, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls) + const char *url, + const char *template_id) +{ + struct TALER_MERCHANT_PostTemplatesHandle *pth; + + pth = GNUNET_new (struct TALER_MERCHANT_PostTemplatesHandle); + pth->ctx = ctx; + pth->base_url = GNUNET_strdup (url); + pth->template_id = GNUNET_strdup (template_id); + return pth; +} + + +enum GNUNET_GenericReturnValue +TALER_MERCHANT_post_templates_set_options_ ( + struct TALER_MERCHANT_PostTemplatesHandle *pth, + unsigned int num_options, + const struct TALER_MERCHANT_PostTemplatesOptionValue *options) +{ + for (unsigned int i = 0; i < num_options; i++) + { + switch (options[i].option) + { + case TALER_MERCHANT_POST_TEMPLATES_OPTION_END: + return GNUNET_OK; + case TALER_MERCHANT_POST_TEMPLATES_OPTION_SUMMARY: + pth->summary = options[i].details.summary; + break; + case TALER_MERCHANT_POST_TEMPLATES_OPTION_AMOUNT: + pth->amount = options[i].details.amount; + break; + case TALER_MERCHANT_POST_TEMPLATES_OPTION_DETAILS: + pth->details = options[i].details.details; + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum TALER_ErrorCode +TALER_MERCHANT_post_templates_start ( + struct TALER_MERCHANT_PostTemplatesHandle *pth, + TALER_MERCHANT_PostTemplatesCallback cb, + TALER_MERCHANT_POST_TEMPLATES_RESULT_CLOSURE *cb_cls) { - struct TALER_MERCHANT_UsingTemplatesPostHandle *utph; + json_t *req_obj; + CURL *eh; - utph = GNUNET_new (struct TALER_MERCHANT_UsingTemplatesPostHandle); - utph->ctx = ctx; - utph->cb = cb; - utph->cb_cls = cb_cls; + pth->cb = cb; + pth->cb_cls = cb_cls; { char *path; GNUNET_asprintf (&path, "templates/%s", - template_id); - utph->url = TALER_url_join (backend_url, - path, - NULL); + pth->template_id); + pth->url = TALER_url_join (pth->base_url, + path, + NULL); GNUNET_free (path); } - if (NULL == utph->url) + if (NULL == pth->url) + return TALER_EC_GENERIC_CONFIGURATION_INVALID; + if (NULL != pth->details) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not construct request URL.\n"); - json_decref (req_obj); - GNUNET_free (utph); - return NULL; + /* If detailed contract customization is provided, send it directly. */ + req_obj = json_incref ((json_t *) pth->details); } + else { - CURL *eh; - - eh = TALER_MERCHANT_curl_easy_get_ (utph->url); - GNUNET_assert (GNUNET_OK == - TALER_curl_easy_post (&utph->post_ctx, - eh, - req_obj)); - json_decref (req_obj); - utph->job = GNUNET_CURL_job_add2 (ctx, - eh, - utph->post_ctx.headers, - &handle_post_using_templates_finished, - utph); - GNUNET_assert (NULL != utph->job); + /* Build fixed-order request with optional summary and amount. */ + req_obj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("template_type", + "fixed-order"), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("summary", + pth->summary)), + GNUNET_JSON_pack_allow_null ( + TALER_JSON_pack_amount ("amount", + pth->amount))); } - return utph; -} - - -struct TALER_MERCHANT_UsingTemplatesPostHandle * -TALER_MERCHANT_using_templates_post ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - const char *summary, - const struct TALER_Amount *amount, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls) -{ - json_t *req_obj; - - req_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("template_type", - "fixed-order"), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("summary", - summary)), - GNUNET_JSON_pack_allow_null ( - TALER_JSON_pack_amount ("amount", - amount))); - return using_templates_post_internal (ctx, - backend_url, - template_id, - req_obj, - cb, - cb_cls); -} - - -struct TALER_MERCHANT_UsingTemplatesPostHandle * -TALER_MERCHANT_using_templates_post2 ( - struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *template_id, - const json_t *details, - TALER_MERCHANT_PostOrdersCallback cb, - void *cb_cls) -{ - if (NULL == details) + eh = TALER_MERCHANT_curl_easy_get_ (pth->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&pth->post_ctx, + eh, + req_obj)) ) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No request body provided for using templates.\n"); - return NULL; + GNUNET_break (0); + json_decref (req_obj); + if (NULL != eh) + curl_easy_cleanup (eh); + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; } - return using_templates_post_internal (ctx, - backend_url, - template_id, - (json_t *) details, - cb, - cb_cls); + json_decref (req_obj); + pth->job = GNUNET_CURL_job_add2 (pth->ctx, + eh, + pth->post_ctx.headers, + &handle_post_templates_finished, + pth); + if (NULL == pth->job) + return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + return TALER_EC_NONE; } void -TALER_MERCHANT_using_templates_post_cancel ( - struct TALER_MERCHANT_UsingTemplatesPostHandle *utph) +TALER_MERCHANT_post_templates_cancel ( + struct TALER_MERCHANT_PostTemplatesHandle *pth) { - if (NULL != utph->job) + if (NULL != pth->job) { - GNUNET_CURL_job_cancel (utph->job); - utph->job = NULL; + GNUNET_CURL_job_cancel (pth->job); + pth->job = NULL; } - TALER_curl_easy_post_finished (&utph->post_ctx); - GNUNET_free (utph->url); - GNUNET_free (utph); + TALER_curl_easy_post_finished (&pth->post_ctx); + GNUNET_free (pth->template_id); + GNUNET_free (pth->url); + GNUNET_free (pth->base_url); + GNUNET_free (pth); } -/* end of merchant_api_post_using_templates.c */ +/* end of merchant_api_post-templates-TEMPLATE_ID-new.c */ diff --git a/src/testing/testing_api_cmd_abort_order.c b/src/testing/testing_api_cmd_abort_order.c @@ -27,7 +27,7 @@ #include <taler/taler_signatures.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-orders-ORDER_ID-abort-new.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-abort.h> /** * State for a " abort" CMD. diff --git a/src/testing/testing_api_cmd_claim_order.c b/src/testing/testing_api_cmd_claim_order.c @@ -27,7 +27,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-orders-ORDER_ID-claim-new.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-claim.h> /** * State for a "order claim" CMD. Not used by diff --git a/src/testing/testing_api_cmd_config.c b/src/testing/testing_api_cmd_config.c @@ -27,7 +27,7 @@ #include <taler/taler_exchange_service.h> #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-config-new.h> +#include <taler/taler-merchant/get-config.h> /** diff --git a/src/testing/testing_api_cmd_delete_account.c b/src/testing/testing_api_cmd_delete_account.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-accounts-H_WIRE-new.h> +#include <taler/taler-merchant/delete-private-accounts-H_WIRE.h> /** diff --git a/src/testing/testing_api_cmd_delete_donau_instances.c b/src/testing/testing_api_cmd_delete_donau_instances.c @@ -25,7 +25,7 @@ #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" #include "taler/taler_merchant_donau.h" -#include <taler/taler-merchant/delete-private-donau-DONAU_SERIAL-new.h> +#include <taler/taler-merchant/delete-private-donau-DONAU_SERIAL.h> /** * State for DELETE /donau/$charity_id testing command. diff --git a/src/testing/testing_api_cmd_delete_instance.c b/src/testing/testing_api_cmd_delete_instance.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-management-instances-INSTANCE-new.h> +#include <taler/taler-merchant/delete-management-instances-INSTANCE.h> /** diff --git a/src/testing/testing_api_cmd_delete_order.c b/src/testing/testing_api_cmd_delete_order.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-orders-ORDER_ID-new.h> +#include <taler/taler-merchant/delete-private-orders-ORDER_ID.h> /** diff --git a/src/testing/testing_api_cmd_delete_otp_device.c b/src/testing/testing_api_cmd_delete_otp_device.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-otp-devices-DEVICE_ID-new.h> +#include <taler/taler-merchant/delete-private-otp-devices-DEVICE_ID.h> /** diff --git a/src/testing/testing_api_cmd_delete_product.c b/src/testing/testing_api_cmd_delete_product.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-products-PRODUCT_ID-new.h> +#include <taler/taler-merchant/delete-private-products-PRODUCT_ID.h> /** diff --git a/src/testing/testing_api_cmd_delete_template.c b/src/testing/testing_api_cmd_delete_template.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-templates-TEMPLATE_ID-new.h> +#include <taler/taler-merchant/delete-private-templates-TEMPLATE_ID.h> /** diff --git a/src/testing/testing_api_cmd_delete_transfer.c b/src/testing/testing_api_cmd_delete_transfer.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-transfers-TID-new.h> +#include <taler/taler-merchant/delete-private-transfers-TID.h> /** diff --git a/src/testing/testing_api_cmd_delete_unit.c b/src/testing/testing_api_cmd_delete_unit.c @@ -25,7 +25,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-units-UNIT-new.h> +#include <taler/taler-merchant/delete-private-units-UNIT.h> /** diff --git a/src/testing/testing_api_cmd_delete_webhook.c b/src/testing/testing_api_cmd_delete_webhook.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID-new.h> +#include <taler/taler-merchant/delete-private-webhooks-WEBHOOK_ID.h> /** diff --git a/src/testing/testing_api_cmd_forget_order.c b/src/testing/testing_api_cmd_forget_order.c @@ -27,7 +27,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-private-orders-ORDER_ID-forget-new.h> +#include <taler/taler-merchant/patch-private-orders-ORDER_ID-forget.h> /** diff --git a/src/testing/testing_api_cmd_get_donau_instances.c b/src/testing/testing_api_cmd_get_donau_instances.c @@ -28,7 +28,7 @@ #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" #include "taler/taler_merchant_donau.h" -#include <taler/taler-merchant/get-private-donau-new.h> +#include <taler/taler-merchant/get-private-donau.h> /** * State of a "GET donau instances" CMD. diff --git a/src/testing/testing_api_cmd_get_instance.c b/src/testing/testing_api_cmd_get_instance.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-management-instances-INSTANCE-new.h> +#include <taler/taler-merchant/get-management-instances-INSTANCE.h> /** diff --git a/src/testing/testing_api_cmd_get_instances.c b/src/testing/testing_api_cmd_get_instances.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-management-instances-new.h> +#include <taler/taler-merchant/get-management-instances.h> /** diff --git a/src/testing/testing_api_cmd_get_orders.c b/src/testing/testing_api_cmd_get_orders.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-orders-new.h> +#include <taler/taler-merchant/get-private-orders.h> /** diff --git a/src/testing/testing_api_cmd_get_otp_device.c b/src/testing/testing_api_cmd_get_otp_device.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-otp-devices-DEVICE_ID-new.h> +#include <taler/taler-merchant/get-private-otp-devices-DEVICE_ID.h> /** diff --git a/src/testing/testing_api_cmd_get_otp_devices.c b/src/testing/testing_api_cmd_get_otp_devices.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-otp-devices-new.h> +#include <taler/taler-merchant/get-private-otp-devices.h> /** diff --git a/src/testing/testing_api_cmd_get_product.c b/src/testing/testing_api_cmd_get_product.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-products-PRODUCT_ID-new.h> +#include <taler/taler-merchant/get-private-products-PRODUCT_ID.h> /** diff --git a/src/testing/testing_api_cmd_get_product_image.c b/src/testing/testing_api_cmd_get_product_image.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-products-IMAGE_HASH-image-new.h> +#include <taler/taler-merchant/get-products-IMAGE_HASH-image.h> /** diff --git a/src/testing/testing_api_cmd_get_products.c b/src/testing/testing_api_cmd_get_products.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-products-new.h> +#include <taler/taler-merchant/get-private-products.h> /** diff --git a/src/testing/testing_api_cmd_get_statisticsamount.c b/src/testing/testing_api_cmd_get_statisticsamount.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-statistics-amount-SLUG-new.h> +#include <taler/taler-merchant/get-private-statistics-amount-SLUG.h> /** diff --git a/src/testing/testing_api_cmd_get_statisticscounter.c b/src/testing/testing_api_cmd_get_statisticscounter.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-statistics-counter-SLUG-new.h> +#include <taler/taler-merchant/get-private-statistics-counter-SLUG.h> /** diff --git a/src/testing/testing_api_cmd_get_template.c b/src/testing/testing_api_cmd_get_template.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-templates-TEMPLATE_ID-new.h> +#include <taler/taler-merchant/get-private-templates-TEMPLATE_ID.h> /** diff --git a/src/testing/testing_api_cmd_get_templates.c b/src/testing/testing_api_cmd_get_templates.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-templates-new.h> +#include <taler/taler-merchant/get-private-templates.h> /** diff --git a/src/testing/testing_api_cmd_get_transfers.c b/src/testing/testing_api_cmd_get_transfers.c @@ -27,7 +27,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-transfers-new.h> +#include <taler/taler-merchant/get-private-transfers.h> /** diff --git a/src/testing/testing_api_cmd_get_unit.c b/src/testing/testing_api_cmd_get_unit.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-units-UNIT-new.h> +#include <taler/taler-merchant/get-private-units-UNIT.h> /** diff --git a/src/testing/testing_api_cmd_get_units.c b/src/testing/testing_api_cmd_get_units.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-units-new.h> +#include <taler/taler-merchant/get-private-units.h> /** diff --git a/src/testing/testing_api_cmd_get_webhook.c b/src/testing/testing_api_cmd_get_webhook.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-webhooks-WEBHOOK_ID-new.h> +#include <taler/taler-merchant/get-private-webhooks-WEBHOOK_ID.h> /** diff --git a/src/testing/testing_api_cmd_get_webhooks.c b/src/testing/testing_api_cmd_get_webhooks.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-webhooks-new.h> +#include <taler/taler-merchant/get-private-webhooks.h> /** diff --git a/src/testing/testing_api_cmd_instance_auth.c b/src/testing/testing_api_cmd_instance_auth.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-management-instances-INSTANCE-auth-new.h> +#include <taler/taler-merchant/post-management-instances-INSTANCE-auth.h> /** diff --git a/src/testing/testing_api_cmd_instance_token.c b/src/testing/testing_api_cmd_instance_token.c @@ -26,8 +26,8 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/delete-private-tokens-SERIAL-new.h> -#include <taler/taler-merchant/post-private-token-new.h> +#include <taler/taler-merchant/delete-private-tokens-SERIAL.h> +#include <taler/taler-merchant/post-private-token.h> /** diff --git a/src/testing/testing_api_cmd_kyc_get.c b/src/testing/testing_api_cmd_kyc_get.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-kyc-new.h> +#include <taler/taler-merchant/get-private-kyc.h> /** diff --git a/src/testing/testing_api_cmd_lock_product.c b/src/testing/testing_api_cmd_lock_product.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-products-PRODUCT_ID-lock-new.h> +#include <taler/taler-merchant/post-private-products-PRODUCT_ID-lock.h> /** diff --git a/src/testing/testing_api_cmd_merchant_get_order.c b/src/testing/testing_api_cmd_merchant_get_order.c @@ -25,7 +25,7 @@ #include <taler/taler_exchange_service.h> #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-private-orders-ORDER_ID-new.h> +#include <taler/taler-merchant/get-private-orders-ORDER_ID.h> /** diff --git a/src/testing/testing_api_cmd_patch_instance.c b/src/testing/testing_api_cmd_patch_instance.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-management-instances-INSTANCE-new.h> +#include <taler/taler-merchant/patch-management-instances-INSTANCE.h> /** diff --git a/src/testing/testing_api_cmd_patch_otp_device.c b/src/testing/testing_api_cmd_patch_otp_device.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-private-otp-devices-DEVICE_ID-new.h> +#include <taler/taler-merchant/patch-private-otp-devices-DEVICE_ID.h> /** diff --git a/src/testing/testing_api_cmd_patch_product.c b/src/testing/testing_api_cmd_patch_product.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-private-products-PRODUCT_ID-new.h> +#include <taler/taler-merchant/patch-private-products-PRODUCT_ID.h> /** diff --git a/src/testing/testing_api_cmd_patch_template.c b/src/testing/testing_api_cmd_patch_template.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-private-templates-TEMPLATE_ID-new.h> +#include <taler/taler-merchant/patch-private-templates-TEMPLATE_ID.h> /** diff --git a/src/testing/testing_api_cmd_patch_unit.c b/src/testing/testing_api_cmd_patch_unit.c @@ -25,7 +25,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-private-units-UNIT-new.h> +#include <taler/taler-merchant/patch-private-units-UNIT.h> /** diff --git a/src/testing/testing_api_cmd_patch_webhook.c b/src/testing/testing_api_cmd_patch_webhook.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID-new.h> +#include <taler/taler-merchant/patch-private-webhooks-WEBHOOK_ID.h> /** diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c @@ -34,7 +34,7 @@ #include <taler/taler_signatures.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-orders-ORDER_ID-pay-new.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-pay.h> #ifdef HAVE_DONAU_DONAU_SERVICE_H #include <donau/donau_service.h> diff --git a/src/testing/testing_api_cmd_post_account.c b/src/testing/testing_api_cmd_post_account.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-accounts-new.h> +#include <taler/taler-merchant/post-private-accounts.h> /** diff --git a/src/testing/testing_api_cmd_post_categories.c b/src/testing/testing_api_cmd_post_categories.c @@ -24,7 +24,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-categories-new.h> +#include <taler/taler-merchant/post-private-categories.h> /** * State of a "POST /private/categories" CMD. diff --git a/src/testing/testing_api_cmd_post_donau_instances.c b/src/testing/testing_api_cmd_post_donau_instances.c @@ -30,7 +30,7 @@ #include "taler/taler_merchant_testing_lib.h" #include "taler/taler_merchant_donau.h" #include <donau/donau_testing_lib.h> -#include <taler/taler-merchant/post-private-donau-new.h> +#include <taler/taler-merchant/post-private-donau.h> /** diff --git a/src/testing/testing_api_cmd_post_instances.c b/src/testing/testing_api_cmd_post_instances.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-management-instances-new.h> +#include <taler/taler-merchant/post-management-instances.h> /** diff --git a/src/testing/testing_api_cmd_post_orders.c b/src/testing/testing_api_cmd_post_orders.c @@ -35,8 +35,8 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-orders-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-claim-new.h> +#include <taler/taler-merchant/post-private-orders.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-claim.h> /** * State for a "POST /orders" CMD. diff --git a/src/testing/testing_api_cmd_post_orders_paid.c b/src/testing/testing_api_cmd_post_orders_paid.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-orders-ORDER_ID-paid-new.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-paid.h> /** diff --git a/src/testing/testing_api_cmd_post_otp_devices.c b/src/testing/testing_api_cmd_post_otp_devices.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-otp-devices-new.h> +#include <taler/taler-merchant/post-private-otp-devices.h> /** diff --git a/src/testing/testing_api_cmd_post_products.c b/src/testing/testing_api_cmd_post_products.c @@ -25,7 +25,7 @@ #include <taler/taler_exchange_service.h> #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-products-new.h> +#include <taler/taler-merchant/post-private-products.h> /** diff --git a/src/testing/testing_api_cmd_post_templates.c b/src/testing/testing_api_cmd_post_templates.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-templates-new.h> +#include <taler/taler-merchant/post-private-templates.h> /** diff --git a/src/testing/testing_api_cmd_post_tokenfamilies.c b/src/testing/testing_api_cmd_post_tokenfamilies.c @@ -28,7 +28,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-tokenfamilies-new.h> +#include <taler/taler-merchant/post-private-tokenfamilies.h> /** diff --git a/src/testing/testing_api_cmd_post_transfers.c b/src/testing/testing_api_cmd_post_transfers.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-transfers-new.h> +#include <taler/taler-merchant/post-private-transfers.h> /** diff --git a/src/testing/testing_api_cmd_post_units.c b/src/testing/testing_api_cmd_post_units.c @@ -25,7 +25,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-units-new.h> +#include <taler/taler-merchant/post-private-units.h> /** diff --git a/src/testing/testing_api_cmd_post_using_templates.c b/src/testing/testing_api_cmd_post_using_templates.c @@ -26,8 +26,8 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-templates-TEMPLATE_ID-new.h> -#include <taler/taler-merchant/post-orders-ORDER_ID-claim-new.h> +#include <taler/taler-merchant/post-templates-TEMPLATE_ID.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-claim.h> /** diff --git a/src/testing/testing_api_cmd_post_webhooks.c b/src/testing/testing_api_cmd_post_webhooks.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-webhooks-new.h> +#include <taler/taler-merchant/post-private-webhooks.h> /** diff --git a/src/testing/testing_api_cmd_refund_order.c b/src/testing/testing_api_cmd_refund_order.c @@ -27,7 +27,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-private-orders-ORDER_ID-refund-new.h> +#include <taler/taler-merchant/post-private-orders-ORDER_ID-refund.h> /** diff --git a/src/testing/testing_api_cmd_wallet_get_order.c b/src/testing/testing_api_cmd_wallet_get_order.c @@ -26,7 +26,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-orders-ORDER_ID-new.h> +#include <taler/taler-merchant/get-orders-ORDER_ID.h> /** diff --git a/src/testing/testing_api_cmd_wallet_get_template.c b/src/testing/testing_api_cmd_wallet_get_template.c @@ -24,7 +24,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/get-templates-TEMPLATE_ID-new.h> +#include <taler/taler-merchant/get-templates-TEMPLATE_ID.h> /** * State of a "GET template" wallet CMD. diff --git a/src/testing/testing_api_cmd_wallet_post_orders_refund.c b/src/testing/testing_api_cmd_wallet_post_orders_refund.c @@ -27,7 +27,7 @@ #include <taler/taler_testing_lib.h> #include "taler/taler_merchant_service.h" #include "taler/taler_merchant_testing_lib.h" -#include <taler/taler-merchant/post-orders-ORDER_ID-refund-new.h> +#include <taler/taler-merchant/post-orders-ORDER_ID-refund.h> /**