commit 54249ff93d61e2261c26349c1fb04e18ce6f37de
parent 2638c25c749fb89274c9a3bf4615da4553e34f12
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 28 Oct 2025 22:41:14 +0100
spec merchant protocol v23 with fix for #9360
Diffstat:
3 files changed, 174 insertions(+), 38 deletions(-)
diff --git a/core/api-merchant.rst b/core/api-merchant.rst
@@ -172,7 +172,7 @@ such as the implemented version of the protocol and the currency used.
.. http:get:: /config
Return the protocol version and currency supported by this merchant backend.
- This specification corresponds to ``current`` protocol being version **v22**.
+ This specification corresponds to ``current`` protocol being version **v23**.
**Response:**
@@ -259,12 +259,6 @@ such as the implemented version of the protocol and the currency used.
// proper i18n and spec/code reuse.
payment_target_regex? string;
- // Default wire transfer delay for new instances.
- // This is the default to use for new instances, see the instance value for
- // the instance-specific default.
- // @since **v22**
- default_wire_transfer_delay: RelativeTime;
-
// Default payment delay for new instances.
// This is the default to use for new instances, see the instance value for
// the instance-specific default.
@@ -277,13 +271,41 @@ such as the implemented version of the protocol and the currency used.
// the instance-specific default.
// @since **v22**
default_refund_delay: RelativeTime;
+
+ // Default wire transfer delay for new instances.
+ // This is the default to use for new instances, see the instance value for
+ // the instance-specific default.
+ // @since **v22**
+ default_wire_transfer_delay: RelativeTime;
+
+ // Default interval to which wire deadlines computed by
+ // adding the wire_transfer_delay on top of the refund
+ // deadline should be rounded up to.
+ // @since **v23**
+ default_wire_transfer_rounding_interval: RoundingInterval;
}
+ .. ts:def:: TanChannel
+
enum TanChannel {
SMS = "sms",
EMAIL = "email"
}
+ .. ts:def:: RoundingInterval
+
+ enum RoundingInterval {
+ NONE = "none",
+ SECOND = "second",
+ MINUTE = "minute",
+ HOUR = "hour",
+ DAY = "day",
+ WEEK = "week",
+ MONTH = "month",
+ QUARTER = "quarter",
+ YEAR = "year"
+ }
+
.. ts:def:: ExchangeConfigInfo
interface ExchangeConfigInfo {
@@ -1475,14 +1497,6 @@ Setting up instances
// Can always be overridden by the frontend on a per-order basis.
use_stefan: boolean;
- // If the frontend does NOT specify an execution date, how long should
- // we tell the exchange to wait to aggregate transactions before
- // executing the wire transfer? This delay is added to the current
- // time when we generate the advisory execution time for the exchange.
- // Optional @since **v22** (before the setting was mandatory).
- // If not provided, the global merchant default will be used.
- default_wire_transfer_delay?: RelativeTime;
-
// If the frontend does NOT specify a payment deadline, how long should
// offers we make be valid by default?
// Optional @since **v22** (before the setting was mandatory).
@@ -1490,10 +1504,25 @@ Setting up instances
default_pay_delay?: RelativeTime;
// If the frontend does NOT specify a refund deadline, how long should
- // refunds be allowed by default?
+ // refunds be allowed by default? Added on top of the
+ // payment deadline.
// @since **v22**
default_refund_delay?: RelativeTime;
+ // If the frontend does NOT specify an execution date, how long should
+ // we tell the exchange to wait to aggregate transactions before
+ // executing the wire transfer? This delay is added on top of
+ // the refund deadline and afterwards subject to rounding
+ // via the ``default_wire_transfer_rounding_interval``.
+ // Optional @since **v22** (before the setting was mandatory).
+ // If not provided, the global merchant default will be used.
+ default_wire_transfer_delay?: RelativeTime;
+
+ // How far should the wire deadline (if computed with the help of
+ // the ``default_wire_transfer_delay``) be rounded up to compute
+ // the ultimate wire deadline?
+ // @since **v22**, defaults to no rounding if not given.
+ default_wire_transfer_rounding_interval?: RoundingInterval;
}
.. http:post:: /management/instances/$INSTANCE/auth
@@ -1781,14 +1810,6 @@ Setting up instances
// Can always be overridden by the frontend on a per-order basis.
use_stefan: boolean;
- // If the frontend does NOT specify an execution date, how long should
- // we tell the exchange to wait to aggregate transactions before
- // executing the wire transfer? This delay is added to the current
- // time when we generate the advisory execution time for the exchange.
- // Optional @since **v22** (before the setting was mandatory).
- // If not provided, the previous setting will now simply be preserved.
- default_wire_transfer_delay?: RelativeTime;
-
// If the frontend does NOT specify a payment deadline, how long should
// offers we make be valid by default?
// Optional @since **v22** (before the setting was mandatory).
@@ -1796,10 +1817,24 @@ Setting up instances
default_pay_delay?: RelativeTime;
// If the frontend does NOT specify a refund deadline, how long should
- // refunds be allowed by default?
+ // refunds be allowed by default? Added on top of the payment deadline.
// @since **v22**
default_refund_delay?: RelativeTime;
+ // If the frontend does NOT specify an execution date, how long should
+ // we tell the exchange to wait to aggregate transactions before
+ // executing the wire transfer? This delay is added on top of
+ // the refund deadline and afterwards subject to rounding
+ // via the ``default_wire_transfer_rounding_interval``.
+ // Optional @since **v22** (before the setting was mandatory).
+ // If not provided, the previous setting will now simply be preserved.
+ default_wire_transfer_delay?: RelativeTime;
+
+ // How far should the wire deadline (if computed with the help of
+ // the ``default_wire_transfer_delay``) be rounded up to compute
+ // the ultimate wire deadline?
+ // @since **v22**, defaults to no rounding if not given.
+ default_wire_transfer_rounding_interval?: RoundingInterval;
}
@@ -1925,21 +1960,29 @@ Inspecting instances
// Can always be overridden by the frontend on a per-order basis.
use_stefan: boolean;
- // If the frontend does NOT specify an execution date, how long should
- // we tell the exchange to wait to aggregate transactions before
- // executing the wire transfer? This delay is added to the current
- // time when we generate the advisory execution time for the exchange.
- default_wire_transfer_delay: RelativeTime;
-
// If the frontend does NOT specify a payment deadline, how long should
- // offers we make be valid by default?
+ // offers we make be valid by default? Added to the order creation
+ // time.
default_pay_delay: RelativeTime;
// If the frontend does NOT specify a refund deadline, how long should
- // refunds be allowed by default?
+ // refunds be allowed by default? Added to the payment deadline.
// @since **v22**
default_refund_delay: RelativeTime;
+ // If the frontend does NOT specify an execution date, how long should
+ // we tell the exchange to wait to aggregate transactions before
+ // executing the wire transfer? This delay is added to the
+ // refund deadline and subject to rounding to the
+ // ``default_wire_transfer_rounding_interval``.
+ default_wire_transfer_delay: RelativeTime;
+
+ // Default interval to which wire deadlines computed by
+ // adding the wire_transfer_delay on top of the refund
+ // deadline should be rounded up to.
+ // @since **v23**
+ default_wire_transfer_rounding_interval: RoundingInterval;
+
// Authentication configuration.
// Does not contain the token when token auth is configured.
auth: {
diff --git a/frags/list-of-dependencies.rst b/frags/list-of-dependencies.rst
@@ -22,7 +22,7 @@
- GNU libmicrohttpd >= 0.9.71
-- GNUnet >= 0.20 (from `source tarball <http://ftpmirror.gnu.org/gnunet/>`__)
+- GNUnet >= 0.25.2 (from `source tarball <http://ftpmirror.gnu.org/gnunet/>`__)
- Python3 with ``jinja2``
diff --git a/taler-merchant-manual.rst b/taler-merchant-manual.rst
@@ -399,6 +399,16 @@ There is no need to actually run a Taler exchange to use the Taler merchant
backend -- all the merchant needs from the Taler exchange is a few headers and
libraries!
+.. note::
+
+ There is an additional **optional** dependency that you could install to
+ obtain support for tax-deductable donations. This is only useful for
+ charities and only in countries with tax authorities that operate a Donau to
+ register charities and accept Taler-style digitally signed donation
+ statements. As of right now, we are pretty sure that list is right now
+ empty. But, if you want to experiment with Taler-style donation statmenets,
+ you need to install Donau after the exchange and before the merchant.
+
.. include:: frags/install-before-check.rst
.. include:: frags/installing-taler-merchant.rst
@@ -502,8 +512,8 @@ To run the Taler backend on TCP port 9966 (the default), use:
Currency
^^^^^^^^
-Which currency the Web shop deals in, i.e. “EUR” or “USD”, is
-specified using the option
+Which currency the SPA uses by default is
+specified using the option:
.. code-block:: ini
@@ -511,7 +521,7 @@ specified using the option
CURRENCY = EUR # or USD, ...
When testing with the Taler demonstration exchange at
-https://exchange.demo.taler.net/ you must set this
+https://exchange.demo.taler.net/ you probably want to set this
value to ``KUDOS``:
.. code-block:: ini
@@ -519,6 +529,11 @@ value to ``KUDOS``:
[MERCHANT]
CURRENCY = KUDOS
+The merchant backend is already multi-currency capable, and will allow you to
+create orders in all currencies for which an exchange is configured, not just
+the default currency. However, the Web interface does not yet offer
+multi-currency support and often only supports using the default currency.
+
.. note::
When using the Debian/Ubuntu packages, these options should be
@@ -709,6 +724,13 @@ merchant backend as ``$USER`` using (to provide a trivial example):
$ taler-merchant-wirewatch &
$ taler-merchant-depositcheck &
$ taler-merchant-exchangekeyupdate &
+ $ taler-merchant-reconciliation &
+
+.. note::
+
+ If you compiled the merchant backend with support for donation
+ statements via Donau, you need to additionally launch
+ ``taler-merchant-donaukeyupdate``.
To ensure these processes run always in the background and also after
rebooting, you should use systemd, cron or some other init system of your
@@ -876,6 +898,76 @@ and the desired access token, click ``confirm``. You can change the instance
settings later via the ``Settings`` entry in the menu on the left.
+Instance settings
+-----------------
+
+The settings dialog allows you to select an image to be used as a logo
+for your shop. Wallets may use that logo when showing contracts to
+highlight to customers which shop they are buying from.
+
+The settings dialog allows you to specify the address of your business
+and the jurisdiction the shop is under. Both will be embedded into the
+contracts and may be shown by the Taler wallet to customers that want
+to know these details.
+
+You must also configure whether you intend to pay transaction fees,
+or whether the customer is required to pay for any payment fees. If
+you do not cover the fees, the fees will be shown separately to the
+customer and added to the total of each order, which may discourage
+consumers from using the Taler payment method. The specific
+magnitude of the fees cannot be configured here, as it depends on
+the amount of the order and is dynamically computed. Regardless of
+what you specify here, the front-end can override the acceptable
+fee amount for each order it creates.
+
+.. note::
+
+ Details on the acceptable fee calcuation
+ are described in the Taler design document 47.
+
+Finally, you need to specify several settings relating to default
+deadlines.
+
+ (1) The "Default payment delay" specifies when an offer expires. The
+ customer basically has this amount of time to pay, or the backend will
+ refuse the payment and require the customer to get a new quote.
+
+ (2) The "Default refund delay" specifies how long the customer may receive
+ refunds. The refund period is cummulative on top of the "Default payment
+ delay". Thus, the refund period ends independently of when the customer
+ actually paid for the order. The exchange will **not** wire the funds to the
+ merchant before the refund deadline lapses, as after the funds have been
+ wired refunds using Taler are no longer possible.
+
+ (3) The "Default wire transfer delay" specifies how soon the exchange
+ **must** wire the funds **after** the refund deadline. The delay is again
+ cummulative on top of the "Default payment delay" and the "Default refund
+ delay". However, the resulting time is still not the actual wire
+ deadline, as first the "Default wire rounding interval" is also considered.
+
+ (4) The "Default wire rounding interval" specifies to what period the
+ wire deadline should be rounded up to. The ultimate wire deadline is
+ computed by adding the default payment, rounding and wire delays to
+ the current time and rounding the resulting timestamp to the
+ "Default wire rounding interval". Typical values include
+ end-of-day, end-of-week, end-of-month, end-of-quarter or end-of-year.
+
+.. note::
+
+ The wire deadline is rounded using the local timezone of the Taler merchant
+ backend server, so if you want end-of-day payments make sure to run your
+ merchant backend in your own timezone.
+
+Specifying larger values for the wire transfer delay and the wire rounding
+interval allows the exchange to aggregate more payments into larger wire
+transfers. The exchange is required by the protocol to initiate the wire
+transfer **before** the wire transfer deadline.
+
+All of the computed deadlines (payment, refund and wire transfer)
+are just defaults and can be modified by frontends for any
+specific order.
+
+
Instance setup without the Web interface
----------------------------------------
@@ -894,8 +986,9 @@ interface create a file ``instance.json`` with an
"auth": { "method" : "external"} ,
"jurisdiction": { "country" : "zz" },
"use_stefan": true,
- "default_wire_transfer_delay": { "d_ms" : 1209600000 },
"default_pay_delay": { "d_ms" : 1209600000 }
+ "default_refund_delay": { "d_ms" : 1209600000 }
+ "default_wire_transfer_delay": { "d_ms" : 1209600000 },
}
The ``name`` field will be shown as the name of your shop. The ``address``