commit 50222a7ea8436b6e7210d7c67807e5d61400899e
parent e25c28c264b3d5eafb2402efda9051e4e9e145fd
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 22 Dec 2025 20:41:35 +0100
new DDs for taxes and notifications
Diffstat:
3 files changed, 266 insertions(+), 0 deletions(-)
diff --git a/design-documents/078-taxes.rst b/design-documents/078-taxes.rst
@@ -0,0 +1,156 @@
+DD 78: Taxes
+############
+
+Summary
+=======
+
+We've received various requests for the merchant backend to provide
+transaction reports for accountants. While not always stated explicitly, we
+believe this is largely also related to tax reporting. This document explains
+the plan for how we intend to deal with periodic reporting.
+
+Motivation
+==========
+
+Making tax-reporting easy for merchants will lower the barrier for them to
+adopt GNU Taler. Furthermore, customers will often require receipts which
+state the specific tax amounts that were paid, so including tax information in
+digital receipts (and thus the Taler contracts) is important. The current
+situation where taxes are specified per-product is not great, as a merchant
+would have to update all products if a tax-percentage were to change, and also
+has to re-calculate the tax every time a product price changes.
+
+
+Requirements
+============
+
+* Deal with the complexity of tax calculations across different jurisdictions.
+ Sure, we may not cover all cases globally, but we should at least cover the
+ most common scenarios. This likely includes different ways how taxes
+ should be computed in terms of rounding, and computing taxes given
+ prices in gross or net amounts.
+* Make it as easy as possible for the merchant to manage taxes. If possible,
+ have some backend-wide defaults so that merchants do not have to enter
+ common taxes that apply across the currency domain.
+* Ensure customers get correct tax receipts as part of their contracts.
+* Incorporate the tax data when informing the merchant about their transaction
+ history, including showing which taxes applied to which purchases so that
+ merchants can easily account for applicable taxes.
+* Treat *donations* and *gifts* as a special-cases as again special tax
+ rules likely apply.
+* A single product may have multiple applicable taxes (say VAT and luxury
+ tax).
+* A single order may contain multiple products (some with known tax
+ rules and others without) and thus a mix of applicable taxes.
+* A merchant may need to override or adapt the tax details for each
+ order, for example because reverse VAT rules may shift the responsibility
+ to pay taxes to the buyer.
+
+
+Proposed Solution
+=================
+
+* Add a table with (0) tax serial number, (1) instance ID, (2) year,
+ (3) tax name, (4) tax rate, (5) tax description, (6) I18n description,
+ (7) rounding mode (up, down, nearest) and (8) rounding unit (amount).
+ to track known tax rules. Unique should be "instance+year+name".
+* When "rounding up" is used, round up from net to gross, but round
+ down from gross to net. Similarly, when "rounding down" is used,
+ round down from net to gross, but round up from gross to net.
+ Finally, "round-to-nearest" implies rounding in the same way for
+ both conversion directions, and rounding up from the exact
+ mid-point between multiples of the rounding unit.
+* Add a new array of applicable taxes to each product, referencing the
+ tax serial numbers.
+* Add a global taxes object to the order/contract terms which
+ maps "year||tax name" to the
+ rates, descriptions, and internationalized descriptions.
+* In addition to the "taxes" array on each product, also have a
+ "taxes" array on each order, giving the total taxes actually
+ applied for the specific order.
+* When creating orders, compute taxes from the product array if
+ possible, but allow client to override the entire array.
+* When overriding, generally allow the client to simply only
+ specify which taxes to apply while doing the calculations in
+ the backend. But do allow a form where the client also does
+ the calculations. The latter should be discouraged as it is
+ likely more error-prone.
+* When generating the contract terms, append the tax details
+ of applicable taxes (rates, descriptions) from the database
+ to the contract. As usual, allow the client to define additional
+ custom tax classes in the order.
+* Add new configuration sections "[taxes-$YEAR-$ID]" that specify common tax
+ classes (name and description as string) and rates (floating point)
+ that should be automatically provided to all instances. When creating
+ a new instance, populate the tax table with these values. Add a
+ command-line tool to add all configured taxes to all existing
+ instances (for example, to update default taxes for the next year).
+* Expand the statistics to include total taxes applied by year and name
+ for the various time intervals for paid orders.
+* Expand the statistics to add up the various brut amounts of products
+ (or orders, given a per-order override) for which a tax was applied.
+ Note that a tax counts as applied if it is listed in the "taxes" array,
+ even if the tax rate is zero (for example, to ensure donations are also
+ totaled up). If a given order or product has multiple taxes associated,
+ the respective total is added to all of those tax classes. If an order
+ consists of taxed products, the taxes for the order are added per
+ product. If the taxes are overriden only for an entire order, the
+ total of the entire order is added to the respective statistics and the
+ individual products and their taxes are ignored (and not reproduced in
+ the contract).
+
+
+Test Plan
+=========
+
+* Unit tests for the rounding functions.
+* Shell-script tests for the CRUD API on taxes and automatic
+ import of tax classes from the configuration.
+* Shell-script tests to check tax calculations in created orders
+ and to test statistics on taxes paid.
+* Manual tests for SPA.
+* Manual tests on PDF report generation.
+* Manual tests on rendering taxes in wallets.
+
+
+Definition of Done
+==================
+
+* Specification updated
+* Database updated
+* Merchant backend updated:
+
+ * CRUD API for tax definitions
+ * INI-based tax class importer
+ * CRUD API update for product management
+ * Order creation update
+ * Statistics update on order paid
+
+* Merchant backend SPA updated:
+
+ * CRUD for tax class definitions
+ * CRUD for associating tax classes with products
+ * Order creation with tax-class override (at least for the entire order,
+ not necessarily per-product)
+ * Statistics page rendering tax statistics
+
+* Wallets updated to render taxes (upon request, in detailed view
+ on payment or from order history)
+
+
+Alternatives
+============
+
+Communism? Crypto-anarchy?
+
+
+Drawbacks
+=========
+
+* Quite a bit of extra complexity
+
+
+Discussion / Q&A
+================
+
+(This should be filled in with results from discussions on mailing lists / personal communication.)
diff --git a/design-documents/079-notifications.rst b/design-documents/079-notifications.rst
@@ -0,0 +1,108 @@
+DD 79: Notifications
+####################
+
+Summary
+=======
+
+Provide a way for merchants to be periodically sent
+reports about payments without requiring them to open
+the merchant backend in a browser.
+
+Motivation
+==========
+
+* We had merchants say that receiving e-mails with
+ transaction statistics is a "MUST" requirement for them
+ (see #10803).
+* We had banks say that sending merchants reports on
+ transaction amounts and especially transaction fees is
+ a legal requirement for them to be able to say that the
+ merchant accepted the fees (see #9361).
+
+Requirements
+============
+
+* Frequencies differ, daily, weekly, monthly, quarterly, yearly
+ are all frequencies we have already been told as desirable.
+* In some cases, an offset is desired, like every day at 3am
+ to ensure business concluded around midnight is included in the
+ "daily" report received in the morning.
+* The reports should include statistics grouped by "category".
+ We are right now interpreting "category" as "tax classes", and
+ thus should report the statistics with the sale amounts in
+ each tax category and the respective amount of taxes due in
+ each category, and the payment fees that were charged ---
+ and the total number of transactions made.
+* We want this to be reasonably generic, so probably best to
+ immediately plan for E-mail, SMS and other transmission mechanisms.
+ So we should use a helper-program for the actual transmission.
+* The target e-mail may not be the public e-mail address associated
+ with the instance.
+* Multiple alerts at different frequencies and different content
+ may apply to the same instance.
+
+
+Proposed Solution
+=================
+
+* Do a "GET" request to some endpoint of the
+ instance to generate the PDF/CSV/TEXT/HTML and then pass that
+ on to the helper program instead of re-implementing the main
+ reporting logic. This way, the configuration would just
+ pick the endpoint (and content-type), which is quite flexible.
+* Add new "notifications" or "alerts" table with
+ (0) serial, (1) instance, (2) name, (3) frequency,
+ (4) time offset, (5) address type, (6) address,
+ (7) mime-type of the data to send, (7) URL
+ path (below /instance/$ID) to request the data from,
+ (8) next-transmission timestamp, (9) last error (EC),
+ (10) last error detail (text).
+* Define helper programs in the configuration for each supported
+ address type that deal with the transmission of the notification.
+* Expose supported notification address types in /config.
+* Add CRUD API to manipulate notification list.
+* Implement helper program that scans the notifications table,
+ requests the data and invokes the helper program for
+ transmission and possibly stores/clears errors.
+
+Test Plan
+=========
+
+* Shell-script based tests for the new CRUD API.
+* Shell-script based tests for notifications using
+ a "cat"-based helper that writes to a local file.
+* Manual tests for SPA.
+* Manual tests for PDF/CSV/etc. generation.
+
+
+Definition of Done
+==================
+
+* Specification updated
+* Database updated
+* Merchant backend updated:
+
+ * CRUD API for notification definitions
+ * INI-based configuration for reporting helper programs
+ * New background process for creating notifications
+ * New endpoints for generating reports (#9361)
+
+* Merchant backend SPA updated:
+
+ * CRUD for notification definitions
+ * Statistics (?) page with links to various
+ GET pages that generate (PDF, CSV) reports (#10487)
+
+
+Alternatives
+============
+
+None.
+
+Drawbacks
+=========
+
+Discussion / Q&A
+================
+
+(This should be filled in with results from discussions on mailing lists / personal communication.)
diff --git a/design-documents/index.rst b/design-documents/index.rst
@@ -89,4 +89,6 @@ Design documents that start with "XX" are considered deprecated.
075-wallet-bban-support
076-paywall-proxy
077-merchant-self-provisioning
+ 078-taxes
+ 079-notifications
999-template