taler-docs

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

commit 7944885e71fbf970d21e0d9f4fe88dcc08146457
parent cb9f87f6db83a3db20c11276512a5906195b667b
Author: Bohdan Potuzhnyi <potub1@bfh.ch>
Date:   Sun, 11 Oct 2026 15:44:31 +0000

adding public units endpoint + fixing a bit the versioning

Diffstat:
Mcore/api-merchant.rst | 30++++++++++++++++++++----------
Mcore/merchant/delete-private-fountains-FOUNTAIN_ID.rst | 2+-
Mcore/merchant/get-fountain-info.rst | 2+-
Mcore/merchant/get-private-fountains-FOUNTAIN_ID.rst | 2+-
Mcore/merchant/get-private-fountains.rst | 5++++-
Mcore/merchant/get-private-otp-devices-DEVICE_ID.rst | 6+++---
Mcore/merchant/get-private-units.rst | 4+++-
Mcore/merchant/patch-private-fountains-FOUNTAIN_ID.rst | 2+-
Mcore/merchant/post-fountain-withdraw.rst | 2+-
Mcore/merchant/post-orders-ORDER_ID-pay.rst | 2+-
Mcore/merchant/post-private-fountains.rst | 2+-
Mcore/merchant/post-private-otp-devices.rst | 10+++++-----
Mcore/merchant/post-templates-TEMPLATE_ID.rst | 2+-
Mdesign-documents/072-products-units.rst | 19+++++++++++++++----
Mdesign-documents/097-challenge-confirmations.rst | 8++++----
Mdesign-documents/098-token-fountains.rst | 12+++++++-----
16 files changed, 69 insertions(+), 41 deletions(-)

diff --git a/core/api-merchant.rst b/core/api-merchant.rst @@ -29,7 +29,7 @@ Merchant Backend RESTful API Version History --------------- -The currently implemented protocol version is **v42**. +The currently implemented protocol version is **v44**. * The Android PoS app is currently targeting **v20**. * The SPA is currently targeting **vXX**. @@ -82,16 +82,24 @@ The currently implemented protocol version is **v42**. ``/private/orders/$ORDER_ID/refund-external`` endpoint for recording externally settled refunds, and exposes both through order status (see :doc:`DD 96 </design-documents/096-partial-payments>`) +* ``v43``: adds ECDSA and EdDSA challenge-based payment confirmations. + The OTP-device API generates signing keys and exposes the public key. + Order creation and template instantiation accept a ``challenge``; after + successful payment, the backend returns its signature in ``pos_confirmation`` + (see :doc:`DD 97 </design-documents/097-challenge-confirmations>`). + Also adds token fountain management and wallet APIs for retrieving grants + and withdrawing blind-signed promotional tokens without creating an order + (see :doc:`DD 98 </design-documents/098-token-fountains>`) +* ``v44``: adds unauthenticated :http:get:`[/instances/$INSTANCE]/units` + to retrieve all active measurement units for one merchant instance, + including built-in units with instance overrides and custom units. + Also adds ``limit``/``offset`` pagination to + :http:get:`[/instances/$INSTANCE]/private/fountains`, using the new + ``fountain_serial`` response field as an exclusive cursor **Upcoming versions:** * ``vTAXES``: adds features to manage taxes -* ``vChallengeConfirmation``: adds challenge-signature OTP algorithms for - payment confirmations verified by offline appliances and tags - (see :doc:`DD 97 </design-documents/097-challenge-confirmations>`) -* ``vTokenFountains``: adds fountains for distributing promotional - merchant tokens - (see :doc:`DD 98 </design-documents/098-token-fountains>`) * ``vDonauReceipts``: returns donation receipts from ``/pay`` in the new ``donau_sigs`` field instead of inside ``token_sigs`` (breaking for orders with a donation receipt output), answers a Donau failure after a @@ -294,10 +302,10 @@ The following permissions exist: * - ``donau-write`` - Adding and removing Donau charity instance links. * - ``fountains-read`` - - Listing and inspecting token fountains. Since **vTokenFountains**. + - Listing and inspecting token fountains. Since **v43**. * - ``fountains-write`` - Creating, modifying and deleting token fountains. - Since **vTokenFountains**. + Since **v43**. * - ``groups-read`` - Listing product groups. * - ``groups-write`` @@ -788,6 +796,8 @@ Decimal quantities Managing measurement units ^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. include:: merchant/get-units.rst + .. include:: merchant/get-private-units.rst .. include:: merchant/get-private-units-UNIT.rst @@ -1341,7 +1351,7 @@ to one recipient or share it for a campaign Wallets receive the credential as a ``taler://fountain/$MERCHANT_HOST[/$INSTANCE_PATH]/$FOUNTAIN_ID/$FOUNTAIN_SECRET`` URI. All fountain endpoints are available since protocol -**vTokenFountains**. +**v43**. Managing fountains ^^^^^^^^^^^^^^^^^^ diff --git a/core/merchant/delete-private-fountains-FOUNTAIN_ID.rst b/core/merchant/delete-private-fountains-FOUNTAIN_ID.rst @@ -4,7 +4,7 @@ Subsequent wallet requests with the fountain secret fail with ``401 Unauthorized``; tokens already withdrawn remain valid until their issue key expires. - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. **Required permission:** ``fountains-write`` (see :ref:`Scopes <merchant-api-scopes>`) diff --git a/core/merchant/get-fountain-info.rst b/core/merchant/get-fountain-info.rst @@ -5,7 +5,7 @@ keys needed to prepare blinded envelopes. Wallets re-poll this endpoint at the advertised ``poll_freq`` to learn about changed promotional grants. - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. The fountain secret authenticates the request via the ``Authorization: Bearer $FOUNTAIN_SECRET`` header; it is diff --git a/core/merchant/get-private-fountains-FOUNTAIN_ID.rst b/core/merchant/get-private-fountains-FOUNTAIN_ID.rst @@ -2,7 +2,7 @@ Returns detailed information about a specific fountain. The fountain secret is never returned. - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. **Required permission:** ``fountains-read`` (see :ref:`Scopes <merchant-api-scopes>`) diff --git a/core/merchant/get-private-fountains.rst b/core/merchant/get-private-fountains.rst @@ -2,7 +2,9 @@ Lists a bounded page of fountains of the instance, ordered by ``fountain_serial``. - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. Pagination and the + ``fountain_serial`` response field are available since protocol **v44**. + Clients must iterate over the pages to retrieve all fountains. **Required permission:** ``fountains-read`` (see :ref:`Scopes <merchant-api-scopes>`) @@ -45,6 +47,7 @@ interface FountainEntry { // Database serial number used as an exclusive pagination cursor. + // Since protocol **v44**. fountain_serial: Integer; // Identifier of the fountain. diff --git a/core/merchant/get-private-otp-devices-DEVICE_ID.rst b/core/merchant/get-private-otp-devices-DEVICE_ID.rst @@ -46,14 +46,14 @@ // 1: TOTP without price // 2: TOTP with price // 3: ECDSA signature over the order's challenge - // (since protocol **vChallengeConfirmation**) + // (since protocol **v43**) // 4: EdDSA signature over the order's challenge - // (since protocol **vChallengeConfirmation**) + // (since protocol **v43**) otp_algorithm: Integer; // Public key of the device key pair, only present for // challenge-signature algorithms (3 and 4). - // Since protocol **vChallengeConfirmation**. + // Since protocol **v43**. otp_device_pub?: string; // Counter for counter-based OTP devices. diff --git a/core/merchant/get-private-units.rst b/core/merchant/get-private-units.rst @@ -1,6 +1,8 @@ .. http:get:: [/instances/$INSTANCE]/private/units - Returns the list of measurement units available to an instance. + Returns the list of measurement units available to an instance, including + inactive definitions. Wallets can retrieve the active catalogue without + authentication using :http:get:`[/instances/$INSTANCE]/units`. **Required permission:** ``units-read`` (see :ref:`Scopes <merchant-api-scopes>`) diff --git a/core/merchant/patch-private-fountains-FOUNTAIN_ID.rst b/core/merchant/patch-private-fountains-FOUNTAIN_ID.rst @@ -4,7 +4,7 @@ replacing the grants does not invalidate the fountain secret; wallets learn about the changed grants on their next ``GET /fountain/info`` poll. - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. **Required permission:** ``fountains-write`` (see :ref:`Scopes <merchant-api-scopes>`) diff --git a/core/merchant/post-fountain-withdraw.rst b/core/merchant/post-fountain-withdraw.rst @@ -5,7 +5,7 @@ structured per grant: each entry addresses one granted token family and one key slot, and carries the envelopes to sign against that grant's limits. - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. The fountain secret travels in the request body, never in the URL. diff --git a/core/merchant/post-orders-ORDER_ID-pay.rst b/core/merchant/post-orders-ORDER_ID-pay.rst @@ -274,7 +274,7 @@ // ("ECDSA_CHALLENGE" or "EDDSA_CHALLENGE"), contains the // Crockford Base32 encoded signature over the hash of the // order's challenge, made with the device private key. - // Since protocol **vChallengeConfirmation**. + // Since protocol **v43**. pos_confirmation?: string; // Signed tokens for the outputs of type ``token``. Returned in diff --git a/core/merchant/post-private-fountains.rst b/core/merchant/post-private-fountains.rst @@ -4,7 +4,7 @@ entitles a wallet to withdraw blind-signed promotional tokens for a set of token families (see :doc:`DD 98 </design-documents/098-token-fountains>`). - This endpoint is available since protocol **vTokenFountains**. + This endpoint is available since protocol **v43**. **Required permission:** ``fountains-write`` (see :ref:`Scopes <merchant-api-scopes>`) diff --git a/core/merchant/post-private-otp-devices.rst b/core/merchant/post-private-otp-devices.rst @@ -17,7 +17,7 @@ ``otp_algorithm`` ("ECDSA_CHALLENGE" or "EDDSA_CHALLENGE"): the backend generated the device key pair and returns a `OtpDeviceCreateResponse` with the public key. - Since protocol **vChallengeConfirmation**. + Since protocol **v43**. :http:statuscode:`400 Bad Request`: The request body is malformed. :http:statuscode:`404 Not found`: @@ -53,7 +53,7 @@ // Taler base32-crockford encoding. // Instead it uses the RFC 3548 encoding to // be compatible with the TOTP standard. - // Since protocol **vChallengeConfirmation** this field is optional: + // Since protocol **v43** this field is optional: // it MUST be omitted for the challenge-signature algorithms // (3 and 4), where the backend generates the key pair itself // and never exposes the private key. @@ -64,9 +64,9 @@ // "TOTP_WITHOUT_PRICE" or 1: Without amounts (typical OTP device) // "TOTP_WITH_PRICE" or 2: With amounts (special-purpose OTP device) // "ECDSA_CHALLENGE" or 3: ECDSA signature over the order's - // challenge, since protocol **vChallengeConfirmation**. + // challenge, since protocol **v43**. // "EDDSA_CHALLENGE" or 4: EdDSA signature over the order's - // challenge, since protocol **vChallengeConfirmation**. + // challenge, since protocol **v43**. // The "string" variants are supported @since protocol **v7**. otp_algorithm: Integer | string; @@ -83,6 +83,6 @@ // For "ECDSA_CHALLENGE" a compressed NIST P-256 point, for // "EDDSA_CHALLENGE" an Ed25519 public key. // Crockford Base32 encoded. - // Since protocol **vChallengeConfirmation**. + // Since protocol **v43**. otp_device_pub: string; } diff --git a/core/merchant/post-templates-TEMPLATE_ID.rst b/core/merchant/post-templates-TEMPLATE_ID.rst @@ -92,7 +92,7 @@ // meaningful -- and then mandatory -- if the template's OTP // device uses a challenge-signature algorithm ("ECDSA_CHALLENGE" // or "EDDSA_CHALLENGE"); rejected otherwise. - // Since protocol **vChallengeConfirmation**. + // Since protocol **v43**. challenge?: string; } diff --git a/design-documents/072-products-units.rst b/design-documents/072-products-units.rst @@ -73,6 +73,13 @@ Proposed Solution ``InternationalizedString`` pattern already used across the API (maps of BCP 47 language tags to translated strings). + Since merchant protocol **v44**, wallets can retrieve all active definitions + through the public :http:get:`[/instances/$INSTANCE]/units` endpoint without + credentials. It returns built-in units with the selected instance's overrides + and that instance's custom units in one response. The unprefixed ``/units`` + path selects the default (``admin``) instance. Inactive units are omitted; + operators can still inspect them through the authenticated private endpoints. + .. http:get:: /private/units Return the catalogue for the current instance. @@ -436,10 +443,14 @@ Proposed Solution When displaying order details or cart lines, wallet and POS front-ends **MUST use the short unit label embedded in the public template response** - for the referenced ``unit``. Wallets cannot call the authenticated - ``/private/units`` endpoints. When no label is supplied, clients fall back - to the raw ``unit`` string. Append the selected label to the numeric value with a - non-breaking thin space (U+202F). Trailing zeros + for the referenced ``unit``. When no label is embedded, wallets can resolve + it using the merchant instance's public ``GET /units`` catalogue. Wallets + cannot call the authenticated ``/private/units`` endpoints. If the unit is + absent or the catalogue cannot be fetched and no label is otherwise + available, clients fall back to the raw ``unit`` string. + + Append the selected label to the numeric value with a non-breaking thin space + (U+202F). Trailing zeros *up to* the declared ``unit_precision_level`` **MUST be trimmed**, but the displayed precision **MUST NOT** exceed the declared level. Examples:: diff --git a/design-documents/097-challenge-confirmations.rst b/design-documents/097-challenge-confirmations.rst @@ -9,8 +9,8 @@ DD 97: Challenge-Signature Payment Confirmations :Historical contributors: Bohdan Potuzhnyi :First published: 2026-07-23 :Last substantive change: 2026-07-23 -:Implementation evidence: ``exchange`` (2026-08-01); ``merchant`` (2026-08-02, not merged into the reviewed HEAD) -:Normative references: ``core/api-merchant.rst`` (upcoming version) and ``core/merchant/post-orders-ORDER_ID-pay.rst`` +:Implementation evidence: ``exchange`` (2026-08-01); ``merchant`` (commit ``8e1875a4``, protocol v43) +:Normative references: ``core/api-merchant.rst`` (v43) and ``core/merchant/post-orders-ORDER_ID-pay.rst`` Summary ======= @@ -23,8 +23,8 @@ action. .. note:: - This design document proposes an extension for discussion. The protocol - version name ``vChallengeConfirmation`` is a placeholder. + The merchant backend implements the API changes described here since + protocol **v43**, replacing the provisional ``vChallengeConfirmation`` name. Motivation ========== diff --git a/design-documents/098-token-fountains.rst b/design-documents/098-token-fountains.rst @@ -9,7 +9,7 @@ DD 98: Token Fountains for Promotions :Historical contributors: Bohdan Potuzhnyi :First published: 2026-07-23 :Last substantive change: 2026-09-06 -:Normative references: ``core/api-merchant.rst`` (upcoming token-fountain API) +:Normative references: ``core/api-merchant.rst`` (v43 token-fountain API) Summary ======= @@ -21,8 +21,9 @@ withdraws blind-signed tokens within limits configured by the institution. .. note:: - This design document proposes an extension for discussion. The protocol - version name ``vTokenFountains`` is a placeholder. + The merchant backend implements the fountain management and wallet APIs + under protocol **v43** (commit ``97439d8f``), replacing the provisional + ``vTokenFountains`` name. Motivation ========== @@ -200,8 +201,9 @@ delete fountains: * ``POST /private/fountains`` -* ``GET /private/fountains`` (paginated listing ordered by fountain serial; - defaults to 20 entries, with a hard cap of 100 per request) +* ``GET /private/fountains`` (since protocol **v44**, paginated listing ordered + by ``fountain_serial`` with ``limit``/``offset`` parameters; defaults to 20 + entries, with a hard cap of 100 per request) * ``GET /private/fountains/$FOUNTAIN_ID``