commit a9422f567486f62c1f8709f7f04e99cac581822a
parent e1231e04f0570f913115c92a0efae1052f0cb886
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 26 Dec 2025 08:48:31 +0100
reports/pots/group specs
Diffstat:
| M | core/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.
+
+
+