taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit a9422f567486f62c1f8709f7f04e99cac581822a
parent e1231e04f0570f913115c92a0efae1052f0cb886
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 26 Dec 2025 08:48:31 +0100

reports/pots/group specs

Diffstat:
Mcore/api-merchant.rst | 609+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 507 insertions(+), 102 deletions(-)

diff --git a/core/api-merchant.rst b/core/api-merchant.rst @@ -29,13 +29,23 @@ Merchant Backend RESTful API Version History --------------- -The current protocol version is ``v20``. +The current protocol version is **v24**. -Android PoS app is currently targeting ``v20``. +Android PoS app is currently targeting **v20**. **Version history:** -* ``v21`` (in development): Adds self-provisioning and two factor authentication. +* ``v21``: Added self-provisioning and two factor authentication +* ``v22``: Added various defaults +* ``v23``: Added various defaults, fields and some new filters +* ``v24``: Make minor changes to refund semantics + +**Upcoming versions:** + +* ``vPOTS``: adds features to group amounts internally (say to + separate tips, taxes and revenue in reporting) +* ``vREPORTS``: adds features for periodic report generation +* ``vTAXES``: adds features to manage taxes ----------------------- Base URLs and Instances @@ -223,6 +233,11 @@ such as the implemented version of the protocol and the currency used. // used with. currencies: { currency : CurrencySpecification}; + // Maps available report generator configuration section names + // to descriptions of the respective report generator. + // Since **vREPORTS**. + report_generators: { section_name : string}; + // Array of exchanges trusted by the merchant. // @since **v6**. exchanges: ExchangeConfigInfo[]; @@ -2952,7 +2967,6 @@ Managing product categories Adding products to the inventory ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - .. http:post:: [/instances/$INSTANCE]/private/products This is used to add a product to the inventory. @@ -2985,6 +2999,12 @@ Adding products to the inventory // moving forward! product_name?: string; + // Product group the product is to be a member of. + // Optional, if missing if the product to be placed + // into the default group. + // Since protocol **vGROUPS**. + product_group_serial?: Integer; + // Human-readable product description. description: string; @@ -3021,6 +3041,11 @@ Adding products to the inventory // by the frontend. unit_price?: Amount[]; + // True if the price(s) given are a net prices, false if they are + // gross prices. + // Since protocol **vTAXES**. + price_is_net?: boolean; + // Legacy price field. Deprecated; when present it must match the first element of ``unit_price``. price?: Amount; @@ -3109,6 +3134,12 @@ Adding products to the inventory // moving forward! product_name?: string; + // Product group the product is a member of. + // Optional, if missing if the product to be placed + // into the default group. + // Since protocol **vGROUPS**. + product_group_serial?: Integer; + // Human-readable product description. description: string; @@ -3185,6 +3216,7 @@ Inspecting inventory :query category_filter: *Optional*. Only returns products that are in a category where the category name contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**. :query name_filter: *Optional*. Only returns products where the product name contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**. :query description_filter: *Optional*. Only returns products where the product description contains the given text as a substring. Matching is case-insensitive. Since protocol **v23**. + :query product_group_serial: *Optional*. Only returns products where the product group serial matches the given value. Since protocol **vGROUPS**. **Response:** @@ -3241,6 +3273,11 @@ Inspecting inventory // Since API version **v20**. product_name: string; + // Product group the product is a member of. + // Optional, missing if the product is in the default group. + // Since protocol **vGROUPS**. + product_group_serial?: Integer; + // Human-readable product description. description: string; @@ -3520,6 +3557,158 @@ Removing products from inventory The backend refuses to delete the product because it is locked. + +-------------- +Product groups +-------------- + +Product groups are used to manage taxes. Each product is in +exactly one group and that group is typically used to determine +the applicable tax rules. Products that are not assigned explicitly +to a group are considered to be in the *default* product group. + +Product groups are different from categories as a product can be +in multiple categories. Furthermore, categories are used to make +it easier to find products in user interfaces, while product +groups are used to make it easier to manage taxes. + +Since protocol **vGROUPS**. + +Adding groups +^^^^^^^^^^^^^ + +.. http:post:: [/instances/$INSTANCES]/private/groups + + This is used to create a report. + + **Required permission:** ``groups-write`` + + **Request:** + + The request must be a `GroupAddRequest`. + + **Response:** + + :http:statuscode:`200 OK`: + The backend has successfully added a new group. Returns a `GroupAddedResponse`. + + :http:statuscode:`404 Not found`: + The merchant instance is unknown. + + **Details:** + + .. ts:def:: GroupAddRequest + + interface GroupAddRequest { + + // Unique name for the group (unique per instance). + group_name: string; + + // Description of the group. + description: string; + + } + + .. ts:def:: GroupAddedResponse + + interface GroupAddedResponse { + + // Unique ID for the group. + group_serial_id: Integer; + + } + + +Editing groups +^^^^^^^^^^^^^^ + +.. http:patch:: [/instances/$INSTANCES]/private/groups/$GROUP_ID + + This is used to update a group. + + **Required permission:** ``groups-write`` + + **Request:** + + The request body must be a `GroupAddRequest`. + + **Response:** + + :http:statuscode:`204 No content`: + The group has successfully modified. + :http:statuscode:`404 Not found`: + The group or instance is unknown to the backend. + :http:statuscode:`409 Conflict`: + The specified group name is already in use. + + +Inspecting groups +^^^^^^^^^^^^^^^^^ + +.. http:get:: [/instances/$INSTANCES]/private/groups + + This is used to return all the groups + that are present in our backend. + + **Required permission:** ``groups-read`` + + **Response:** + + :http:statuscode:`200 OK`: + The backend has successfully returned all the groups. + Returns a `GroupsSummaryResponse`. + + :http:statuscode:`404 Not found`: + The backend has does not know about the instance. + + **Details:** + + .. ts:def:: GroupsSummaryResponse + + interface GroupsSummaryResponse { + + // Return groups that are present in our backend. + groups: GroupEntry[]; + + } + + The `GroupEntry` object describes a group. + It has the following structure: + + .. ts:def:: GroupEntry + + interface GroupEntry { + + // Group identifier + group_serial: Integer; + + // Unique name for the group (unique per instance). + group_name: string; + + // Description for the group. + description: String; + + } + + +Removing groups +^^^^^^^^^^^^^^^ + +.. http:delete:: [/instances/$INSTANCES]/private/groups/$GROUP_SERIAL + + This is used to delete information about a group. + + **Required permission:** ``groups-write`` + + **Response:** + + :http:statuscode:`204 No content`: + The backend has successfully deleted the group. + + :http:statuscode:`404 Not found`: + The group or the instance is unknown to the backend. + + ------------------ Payment processing ------------------ @@ -4120,10 +4309,10 @@ Inspecting orders // available, otherwise empty array. wire_details: TransactionWireTransfer[]; - // Reports about trouble obtaining wire transfer details, + // Groups about trouble obtaining wire transfer details, // empty array if no trouble were encountered. // @deprecated in protocol **v6**. - wire_reports: TransactionWireReport[]; + wire_groups: TransactionWireReport[]; // The refund details for this order. One entry per // refunded coin; empty array if there are no refunds. @@ -5424,7 +5613,7 @@ Inspecting webhook .. http:get:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID - This is used to obtain detailed information about apecific template. + This is used to obtain detailed information about apecific webhook. **Required permission:** ``webhooks-read`` @@ -5478,49 +5667,49 @@ Removing webhook The webhook(ID) or the instance is unknown to the backend. -------------- -Notifications -------------- +------- +Reports +------- -Notifications are a backend feature that is used to send periodic -reports to the merchant. Notifications are sent using notification +Reports are a backend feature that is used to send periodic +reports to the merchant. Reports are sent using notification helper programs which must be configured for each merchant backend. +Since protocol **vREPORTS**. +Adding reports +^^^^^^^^^^^^^^ -Adding notifications -^^^^^^^^^^^^^^^^^^^^ - -.. http:post:: [/instances/$INSTANCES]/private/notifications +.. http:post:: [/instances/$INSTANCES]/private/reports - This is used to create a notification. + This is used to create a report. - **Required permission:** ``notifications-write`` + **Required permission:** ``reports-write`` **Request:** - The request must be a `NotificationAddRequest`. + The request must be a `ReportAddRequest`. **Response:** :http:statuscode:`200 OK`: - The backend has successfully added a new notification. Returns a `NotificationAddedResponse`. + The backend has successfully added a new report. Returns a `ReportAddedResponse`. :http:statuscode:`404 Not found`: The merchant instance is unknown. **Details:** - .. ts:def:: NotificationAddRequest + .. ts:def:: ReportAddRequest - interface NotificationAddRequest { + interface ReportAddRequest { - // Description of the notification. Possibly included - // in the notification message. + // Description of the report. Possibly included + // in the report message. description: string; // Merchant backend configuration section specifying - // the program to use to transmit the notification + // the program to use to transmit the report program_section: string; // Mime-type to request from the data source. @@ -5529,172 +5718,388 @@ Adding notifications // Base URL to request the data from. data_source: string; - // Address where the notification program should send - // the notification. + // Address where the report program should send + // the report. target_address: string; - // Notification frequency - notification_frequency: RelativeTime; + // Report frequency + report_frequency: RelativeTime; - // Notification frequency shift - notification_frequency_shift: Integer; + // Report frequency shift + report_frequency_shift: Integer; } - .. ts:def:: NotificationAddedResponse + .. ts:def:: ReportAddedResponse - interface NotificationAddedResponse { + interface ReportAddedResponse { - // Unique ID for the notification. - notification_serial_id: Integer; + // Unique ID for the report. + report_serial_id: Integer; } -Editing webhooks -^^^^^^^^^^^^^^^^ +Editing reports +^^^^^^^^^^^^^^^ -.. http:patch:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID +.. http:patch:: [/instances/$INSTANCES]/private/reports/$REPORT_ID - This is used to update a webhook. + This is used to update a report. - **Required permission:** ``webhooks-write`` + **Required permission:** ``reports-write`` **Request:** - The request must be a `WebhookPatchDetails`. + The request body must be a `ReportAddRequest`. **Response:** :http:statuscode:`204 No content`: - The webhook has successfully modified. + The report has successfully modified. :http:statuscode:`404 Not found`: - The webhook(ID) is unknown to the backend. - :http:statuscode:`409 Conflict`: - The provided information is inconsistent with the current state of the webhook. Changes made is the same with another store. + The report or instance is unknown to the backend. + + +Inspecting reports +^^^^^^^^^^^^^^^^^^ + +.. http:get:: [/instances/$INSTANCES]/private/reports + + This is used to return all the reports + that are present in our backend. + + **Required permission:** ``reports-read`` + + **Response:** + + :http:statuscode:`200 OK`: + The backend has successfully returned all the reports. + Returns a `ReportsSummaryResponse`. + + :http:statuscode:`404 Not found`: + The backend has does not know about the instance. **Details:** - .. ts:def:: WebhookPatchDetails + .. ts:def:: ReportsSummaryResponse - interface WebhookPatchDetails { + interface ReportsSummaryResponse { - // The event of the webhook: why the webhook is used. - event_type: WebhookEventType; + // Return reports that are present in our backend. + reports: ReportEntry[]; - // URL of the webhook where the customer will be redirected. - url: string; + } - // Method used by the webhook - http_method: string; + The `ReportEntry` object describes a report. + It has the following structure: - // Header template of the webhook - header_template?: string; + .. ts:def:: ReportEntry - // Body template by the webhook - body_template?: string; + interface ReportEntry { - } + // Report identifier + report_serial: Integer; + // Description for the report. + description: String; + // Frequency for the report. + report_frequency: RelativeTime; -Inspecting webhook -^^^^^^^^^^^^^^^^^^ + } -.. http:get:: [/instances/$INSTANCES]/private/webhooks - This is used to return all the webhooks that are present in our backend. +.. http:get:: [/instances/$INSTANCES]/private/reports/$REPORT_SERIAL - **Required permission:** ``webhooks-read`` + This is used to obtain detailed information about apecific report. + + **Required permission:** ``reports-read`` **Response:** :http:statuscode:`200 OK`: - The backend has successfully returned all the webhooks. Returns a `WebhookSummaryResponse`. + The backend has successfully returned the detailed information about a specific report. Returns a `ReportDetailResponse`. :http:statuscode:`404 Not found`: - The backend has does not know about the instance. + The report or instance is unknown to the backend. **Details:** - .. ts:def:: WebhookSummaryResponse + .. ts:def:: ReportDetailResponse - interface WebhookSummaryResponse { + interface ReportDetailResponse { - // Return webhooks that are present in our backend. - webhooks: WebhookEntry[]; + // Report identifier + report_serial: Integer; - } + // Description of the report. Possibly included + // in the report message. + description: string; - The `WebhookEntry` object describes a webhook. It has the following structure: + // Merchant backend configuration section specifying + // the program to use to transmit the report + program_section: string; - .. ts:def:: WebhookEntry + // Mime-type to request from the data source. + mime_type: string; - interface WebhookEntry { + // Base URL to request the data from. + data_source: string; - // Webhook identifier, as found in the webhook. - webhook_id: string; + // Address where the report program should send + // the report. + target_address: string; - // The event of the webhook: why the webhook is used. - event_type: WebhookEventType; + // Report frequency + report_frequency: RelativeTime; - } + // Report frequency shift + report_frequency_shift: Integer; + // Numeric `error code <error-codes>` unique to the + // error encountered in generating the latest report. + // Absent if there was no error. + last_error_code?: Integer; -.. http:get:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID + // Details about any error encountered + // in generating the latest report. + last_error_detail?: string; + } - This is used to obtain detailed information about apecific template. - **Required permission:** ``webhooks-read`` +Removing reports +^^^^^^^^^^^^^^^^ + +.. http:delete:: [/instances/$INSTANCES]/private/reports/$REPORT_SERIAL + + This is used to delete information about a report. + + **Required permission:** ``reports-write`` + + **Response:** + + :http:statuscode:`204 No content`: + The backend has successfully deleted the report. + + :http:statuscode:`404 Not found`: + The report or the instance is unknown to the backend. + + + +---- +Pots +---- + +Pots are a backend feature that is used to send periodic +reports to the merchant. Reports are sent using notification +helper programs which must be configured for each merchant backend. + +Since protocol **vPOTS**. + +Adding pots +^^^^^^^^^^^ + +.. http:post:: [/instances/$INSTANCES]/private/pots + + This is used to create a pot. + + **Required permission:** ``pots-write`` + + **Request:** + + The request must be a `PotAddRequest`. **Response:** :http:statuscode:`200 OK`: - The backend has successfully returned the detailed information about a specific webhook. Returns a `WebhookDetails`. + The backend has successfully added a new pot. Returns a `PotAddedResponse`. :http:statuscode:`404 Not found`: - The webhook(ID) is unknown to the backend. + The merchant instance is unknown. **Details:** - .. ts:def:: WebhookDetails + .. ts:def:: PotAddRequest - interface WebhookDetails { + interface PotAddRequest { - // The event of the webhook: why the webhook is used. - event_type: WebhookEventType; + // Description of the pot. Possibly included + // in the pot message. + description: string; - // URL of the webhook where the customer will be redirected. - url: string; + // Name of the pot. Must be unique per instance. + pot_name: string; - // Method used by the webhook - http_method: string; + // Currency of the pod. Must be a valid Taler currency string. + currency: string; - // Header template of the webhook - header_template?: string; + } - // Body template by the webhook - body_template?: string; + .. ts:def:: PotAddedResponse + + interface PotAddedResponse { + + // Unique ID for the pot. + pot_serial_id: Integer; + + } + + +Editing pots +^^^^^^^^^^^^ + +.. http:patch:: [/instances/$INSTANCES]/private/pots/$POT_ID + + This is used to update a pot. + + **Required permission:** ``pots-write`` + + **Request:** + The request body must be a `PotModifyRequest`. + + **Response:** + + :http:statuscode:`204 No content`: + The pot has successfully modified. + :http:statuscode:`404 Not found`: + The pot or instance is unknown to the backend. + :http:statuscode:`409 Conflict`: + The pot total did not match the expected total + and thus resetting the pod failed. + + **Details:** + + .. ts:def:: PotModifyRequest + + interface PotModifyRequest { + + // Description of the pot. Possibly included + // in the pot message. + description: string; + + // Name of the pot. Must be unique per instance. + pot_name: string; + + // Expected current total amount in the pot. + // Should be given if ``new_pot_total`` is specified + // as this allows checking that the pot total did + // not change in the meantime. + expected_pot_total?: Amount; + + // Expected new total amount to store in the pod. + // Does **not** have to be in the same currency as + // the existing amount in the pot. + new_pot_total?: Amount; } -Removing webhook -^^^^^^^^^^^^^^^^ -.. http:delete:: [/instances/$INSTANCES]/private/webhooks/$WEBHOOK_ID +Inspecting pots +^^^^^^^^^^^^^^^ - This is used to delete information about a webhook. +.. http:get:: [/instances/$INSTANCES]/private/pots - **Required permission:** ``webhooks-write`` + This is used to return all the pots + that are present in our backend. + + **Required permission:** ``pots-read`` + + **Response:** + + :http:statuscode:`200 OK`: + The backend has successfully returned all the pots. + Returns a `PotsSummaryResponse`. + + :http:statuscode:`404 Not found`: + The backend has does not know about the instance. + + **Details:** + + .. ts:def:: PotsSummaryResponse + + interface PotsSummaryResponse { + + // Return pots that are present in our backend. + pots: PotEntry[]; + + } + + The `PotEntry` object describes a pot. + It has the following structure: + + .. ts:def:: PotEntry + + interface PotEntry { + + // Pot identifier + pot_serial: Integer; + + // Name of the pot. Must be unique per instance. + pot_name: string; + + // Current total amount in the pod. + pot_total: Amount; + + } + + +.. http:get:: [/instances/$INSTANCES]/private/pots/$POT_SERIAL + + This is used to obtain detailed information about apecific pot. + + **Required permission:** ``pots-read`` + + **Response:** + + :http:statuscode:`200 OK`: + The backend has successfully returned the detailed information about a specific pot. Returns a `PotDetailResponse`. + + :http:statuscode:`404 Not found`: + The pot or instance is unknown to the backend. + + **Details:** + + .. ts:def:: PotDetailResponse + + interface PotDetailResponse { + + // Pot identifier + pot_serial: Integer; + + // Description of the pot. Possibly included + // in the pot message. + description: string; + + // Name of the pot. Must be unique per instance. + pot_name: string; + + // Current total amount in the pod. + pot_total: Amount; + + } + + +Removing pots +^^^^^^^^^^^^^ + +.. http:delete:: [/instances/$INSTANCES]/private/pots/$POT_SERIAL + + This is used to delete information about a pot. + + **Required permission:** ``pots-write`` **Response:** :http:statuscode:`204 No content`: - The backend has successfully deleted the webhook. + The backend has successfully deleted the pot. :http:statuscode:`404 Not found`: - The webhook(ID) or the instance is unknown to the backend. + The pot or the instance is unknown to the backend. + + +