taler-docs

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

commit 716bfcc1c083c4a987e833dc845d078103cad4bf
parent 564f9a34383e2980ac8ebff5626504e9f73835dc
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date:   Wed, 29 Oct 2025 11:40:37 +0100

#0010506

Diffstat:
Mcore/api-merchant.rst | 188++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 139 insertions(+), 49 deletions(-)

diff --git a/core/api-merchant.rst b/core/api-merchant.rst @@ -2683,12 +2683,29 @@ Adding products to the inventory // Unit in which the product is measured (liters, kilograms, packages, etc.). unit: string; - // The price for one ``unit`` of the product. Zero is used - // to imply that this product is not sold separately, or - // that the price is not fixed, and must be supplied by the - // front-end. If non-zero, this price MUST include applicable - // taxes. - price: Amount; + // Optional override to control whether fractional quantities are permitted. + // Defaults to the policy implied by ``unit``. + unit_allow_fraction?: boolean; + + // Override for the fractional precision level (0-6). Only relevant if + // ``unit_allow_fraction`` is true. Defaults come from ``unit``. + unit_precision_level?: Integer; + + // Preferred way to express inventory counts using "<integer>[.<fraction>]" syntax. + // Use "-1" for unlimited stock. Required unless ``total_stock`` is provided. + unit_total_stock?: string; + + // Legacy stock counter. Deprecated, use ``unit_total_stock`` instead. + // Still required when ``unit_total_stock`` is omitted. + total_stock?: Integer; + + // Preferred way to express the per-unit price of the product. Zero implies that + // the product is not sold separately or that the price must be supplied by the frontend. + // If non-zero, this price MUST include applicable taxes. + unit_price?: Amount; + + // Legacy price field. Deprecated; when present it must match ``unit_price``. + price?: Amount; // An optional base64-encoded product image. image?: ImageDataUrl; @@ -2696,12 +2713,6 @@ Adding products to the inventory // A list of taxes paid by the merchant for one unit of this product. taxes?: Tax[]; - // Number of units of the product in stock in sum in total, - // including all existing sales ever. Given in product-specific - // units. - // A value of -1 indicates "infinite" (i.e. for "electronic" books). - total_stock: Integer; - // Identifies where the product is in stock. address?: Location; @@ -2713,6 +2724,32 @@ Adding products to the inventory } + Clients SHOULD migrate to the new ``unit_*`` fields and treat ``total_stock`` and ``price`` + as deprecated compatibility shims. If both the legacy and the new representation are supplied, + their values must match. Omitting both ``unit_total_stock`` and ``total_stock`` (or both + ``unit_price`` and ``price``) results in a ``400 Bad Request``. + + ``unit_total_stock`` uses a fixed-point decimal string in the form ``INTEGER[.FRACTION]`` with + at most eight fractional digits. Scientific notation or special values such as ``NaN`` are not + accepted. Supply ``"-1"`` to represent unlimited stock. + + Fractional behaviour defaults to the value of ``unit``. The backend disables fractions for + ``Piece``, ``Set``, ``Custom``, ``WeightUnitMg`` and ``SizeUnitMm``. Other predefined units + allow fractional quantities with the following default precision levels: + + - Precision ``1``: ``WeightUnitG``, ``SizeUnitCm``, ``SurfaceUnitMm2``, ``VolumeUnitMm3``. + - Precision ``2``: ``WeightUnitOunce``, ``SizeUnitInch``, ``SurfaceUnitCm2``, + ``VolumeUnitInch3``, ``VolumeUnitOunce``, ``TimeUnitHour``, ``TimeUnitMonth``. + - Precision ``3``: ``WeightUnitTon``, ``WeightUnitKg``, ``WeightUnitPound``, ``SizeUnitM``, + ``SizeUnitDm``, ``SizeUnitFoot``, ``SurfaceUnitDm2``, ``SurfaceUnitFoot2``, ``VolumeUnitCm3``, + ``VolumeUnitLitre``, ``VolumeUnitGallon``, ``TimeUnitSecond``, ``TimeUnitMinute``, + ``TimeUnitDay``, ``TimeUnitWeek``. + - Precision ``4``: ``SurfaceUnitM2``, ``SurfaceUnitInch2``, ``TimeUnitYear``. + - Precision ``5``: ``VolumeUnitDm3``, ``VolumeUnitFoot3``. + - Precision ``6``: ``VolumeUnitM3``. + + Integrations can override these defaults by explicitly setting ``unit_allow_fraction`` and/or + ``unit_precision_level``. .. http:patch:: [/instances/$INSTANCE]/private/products/$PRODUCT_ID @@ -2763,17 +2800,25 @@ Adding products to the inventory // Unit in which the product is measured (liters, kilograms, packages, etc.). unit: string; + // Optional override to control whether fractional quantities are permitted. + unit_allow_fraction?: boolean; + + // Override for the fractional precision level (0-6). Only relevant if + // ``unit_allow_fraction`` is true. + unit_precision_level?: Integer; + // Categories into which the product belongs. // Used in the POS-endpoint. // Since API version **v16**. categories?: Integer[]; - // The price for one ``unit`` of the product. Zero is used - // to imply that this product is not sold separately, or - // that the price is not fixed, and must be supplied by the - // front-end. If non-zero, this price MUST include applicable - // taxes. - price: Amount; + // Preferred way to express the per-unit price. Zero implies that + // the product is not sold separately or that the price must be supplied by the frontend. + // If non-zero, this price MUST include applicable taxes. + unit_price?: Amount; + + // Legacy price field. Deprecated; when present it must match ``unit_price``. + price?: Amount; // An optional base64-encoded product image. image?: ImageDataUrl; @@ -2781,11 +2826,12 @@ Adding products to the inventory // A list of taxes paid by the merchant for one unit of this product. taxes?: Tax[]; - // Number of units of the product in stock in sum in total, - // including all existing sales ever. Given in product-specific - // units. - // A value of -1 indicates "infinite" (i.e. for "electronic" books). - total_stock: Integer; + // Preferred way to express inventory counts using "<integer>[.<fraction>]" syntax. + // Use "-1" for unlimited stock. + unit_total_stock?: string; + + // Legacy stock counter. Deprecated, use ``unit_total_stock`` instead. + total_stock?: Integer; // Number of units of the product that were lost (spoiled, stolen, etc.). total_lost?: Integer; @@ -2801,6 +2847,9 @@ Adding products to the inventory } + The same compatibility rules for the ``unit_*`` fields and their deprecated counterparts apply + when patching an existing product. + Inspecting inventory ^^^^^^^^^^^^^^^^^^^^ @@ -2880,15 +2929,22 @@ Inspecting inventory // Unit in which the product is measured (liters, kilograms, packages, etc.). unit: string; + // Does the backend allow fractional quantities for this unit? + unit_allow_fraction: boolean; + + // Maximum fractional precision (0-6) enforced for inventory operations. + unit_precision_level: Integer; + // Categories into which the product belongs. // Since API version **v16**. categories: Integer[]; - // The price for one ``unit`` of the product. Zero is used - // to imply that this product is not sold separately, or - // that the price is not fixed, and must be supplied by the - // front-end. If non-zero, this price MUST include applicable - // taxes. + // Price for one ``unit`` of the product. Zero is used to imply that this product + // is not sold separately, or that the price is not fixed, and must be supplied by the + // front-end. If non-zero, this price MUST include applicable taxes. + unit_price: Amount; + + // Legacy price field kept for compatibility. Deprecated; equal to ``unit_price``. price: Amount; // An optional base64-encoded product image. @@ -2898,12 +2954,13 @@ Inspecting inventory // Optional since **v15**. taxes?: Tax[]; - // Number of units of the product in stock in sum in total, - // including all existing sales ever. Given in product-specific - // units. - // A value of -1 indicates "infinite" (i.e. for "electronic" books). + // Legacy integer stock counter kept for compatibility. ``-1`` indicates unlimited stock. total_stock: Integer; + // Stock expressed using "<integer>[.<fraction>]" syntax with up to eight fractional digits. + // Use ``"-1"`` for unlimited stock. + unit_total_stock: string; + // Number of units of the product that have already been sold. total_sold: Integer; @@ -2979,11 +3036,18 @@ Inspecting inventory // Unit in which the product is measured (liters, kilograms, packages, etc.). unit: string; - // The price for one ``unit`` of the product. Zero is used - // to imply that this product is not sold separately, or - // that the price is not fixed, and must be supplied by the - // front-end. If non-zero, this price MUST include applicable - // taxes. + // Does the backend allow fractional quantities for this unit? + unit_allow_fraction: boolean; + + // Maximum fractional precision (0-6) enforced for inventory operations. + unit_precision_level: Integer; + + // Price for one ``unit`` of the product. Zero is used to imply that this product + // is not sold separately, or that the price is not fixed, and must be supplied by the + // front-end. If non-zero, this price MUST include applicable taxes. + unit_price: Amount; + + // Legacy price field kept for compatibility. Deprecated; equal to ``unit_price``. price: Amount; // An optional base64-encoded product image. @@ -2992,12 +3056,13 @@ Inspecting inventory // A list of taxes paid by the merchant for one unit of this product. taxes?: Tax[]; - // Number of units of the product in stock in sum in total, - // including all existing sales ever. Given in product-specific - // units. - // Optional, if missing treat as "infinite". + // Legacy integer stock counter kept for compatibility. ``-1`` indicates unlimited stock. total_stock?: Integer; + // Stock expressed using "<integer>[.<fraction>]" syntax with up to eight fractional digits. + // Use ``"-1"`` for unlimited stock. + unit_total_stock: string; + // Minimum age buyer must have (in years). minimum_age?: Integer; @@ -3052,7 +3117,7 @@ Reserving inventory :http:statuscode:`404 Not found`: The backend has does not know this product. :http:statuscode:`410 Gone`: - The backend does not have enough of product in stock. + The backend does not have enough of product in stock. Returns an `OutOfStockResponse`. **Details:** @@ -3067,11 +3132,19 @@ Reserving inventory // How long does the frontend intend to hold the lock? duration: RelativeTime; - // How many units should be locked? - quantity: Integer; + // Legacy integer quantity to lock. Deprecated; defaults to 1 if both + // ``quantity`` and ``unit_quantity`` are absent. + quantity?: Integer; + + // Preferred way to express the requested quantity using "<integer>[.<fraction>]" syntax. + unit_quantity?: string; } + At least one of ``quantity`` or ``unit_quantity`` must be supplied; omitting both defaults to a + quantity of one. ``unit_quantity`` follows the same decimal-string format described for + ``unit_total_stock``. + .. note:: The ``GNUNET_CRYPTO_random_timeflake()`` C API can be used @@ -3465,10 +3538,18 @@ Creating orders // Which product is requested (here mandatory!). product_id: string; - // How many units of the product are requested. - quantity: Integer; + // Legacy integer quantity. Deprecated; defaults to 1 if both + // ``quantity`` and ``unit_quantity`` are absent. + quantity?: Integer; + + // Preferred quantity string using "<integer>[.<fraction>]" syntax. + unit_quantity?: string; } + Supply either ``quantity`` or ``unit_quantity`` when referencing inventory products. If both are + missing the backend assumes a quantity of one. ``unit_quantity`` follows the same decimal-string + rules as ``unit_total_stock``. + .. ts:def:: PostOrderResponse interface PostOrderResponse { @@ -3492,12 +3573,18 @@ Creating orders // Product ID of an out-of-stock item. product_id: string; - // Requested quantity. + // Legacy integer quantity requested. Deprecated; see ``unit_requested_quantity``. requested_quantity: Integer; - // Available quantity (must be below ``requested_quantity``). + // Requested quantity using "<integer>[.<fraction>]" syntax with up to eight fractional digits. + unit_requested_quantity: string; + + // Legacy integer availability (must be below ``requested_quantity``). available_quantity: Integer; + // Available quantity using "<integer>[.<fraction>]" syntax with up to eight fractional digits. + unit_available_quantity: string; + // When do we expect the product to be again in stock? // Optional, not given if unknown. restock_expected?: Timestamp; @@ -5805,9 +5892,12 @@ It has the following structure: // Map from IETF BCP 47 language tags to localized descriptions. description_i18n?: { [lang_tag: string]: string }; - // The number of units of the product to deliver to the customer. + // Legacy integer portion of the quantity to deliver defaults to 1 if not specified. quantity?: Integer; + // Preferred quantity string using "<integer>[.<fraction>]" syntax with up to eight fractional digits. + unit_quantity?: string; + // Unit in which the product is measured (liters, kilograms, packages, etc.). unit?: string;