taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 88bf1eef50f5b7137618c4d8a94aadd89bdf31ac
parent 029492fc8dc70bab8ba259dbeddd43a60b81930c
Author: Florian Dold <dold@taler.net>
Date:   Tue,  3 Nov 2026 22:34:51 +0100

taler-util: retain template amount bounds in API codecs

Diffstat:
Mpackages/taler-util/src/types-taler-merchant.test.ts | 17+++++++++++++++++
Mpackages/taler-util/src/types-taler-merchant.ts | 10++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/packages/taler-util/src/types-taler-merchant.test.ts b/packages/taler-util/src/types-taler-merchant.test.ts @@ -17,6 +17,7 @@ import assert from "node:assert"; import { test } from "node:test"; import { + codecForTemplateContractDetails, codecForLoginTokenSuccessResponse, codecForPaymentDeniedLegallyResponse, codecForQueryInstancesResponse, @@ -156,3 +157,19 @@ test("token family details retain arbitrary extra_data", () => { }); assert.deepStrictEqual(decoded.extra_data, extra_data); }); + +for (const template_type of ["fixed-order", "inventory-cart", "paivana"]) { + test(`template amount bounds survive decoding for ${template_type}`, () => { + const contract = codecForTemplateContractDetails().decode({ + template_type, + currency: "CHF", + min_amount: "CHF:0", + max_amount: "CHF:20", + ...(template_type === "paivana" + ? { choices: [{ amount: "CHF:5" }] } + : {}), + }); + assert.strictEqual(contract.min_amount, "CHF:0"); + assert.strictEqual(contract.max_amount, "CHF:20"); + }); +} diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts @@ -3311,6 +3311,10 @@ export interface TemplateContractCommon { // if "amount" is given. currency?: string; + // Inclusive cart/amount bounds excluding tips, in currency. Since v34. + min_amount?: AmountString; + max_amount?: AmountString; + // The time the customer need to pay before his order will be deleted. // It is deleted if the customer did not pay and if the duration is over. pay_duration?: RelativeTime; @@ -5144,6 +5148,8 @@ export const codecForTemplateContractPaivana = .property("website_regex", codecOptional(codecForString())) .property("currency", codecOptional(codecForString())) + .property("min_amount", codecOptional(codecForAmountString())) + .property("max_amount", codecOptional(codecForAmountString())) .property("max_pickup_duration", codecOptional(codecForDuration)) .property("minimum_age", codecOptional(codecForNumber())) .property("pay_duration", codecOptional(codecForDuration)) @@ -5180,6 +5186,8 @@ export const codecForTemplateContractInventoryCart = .property("inventory_payload", codecOptional(codecForAny())) // FIXME: validate .property("currency", codecOptional(codecForString())) + .property("min_amount", codecOptional(codecForAmountString())) + .property("max_amount", codecOptional(codecForAmountString())) .property("max_pickup_duration", codecOptional(codecForDuration)) .property("minimum_age", codecOptional(codecForNumber())) .property("pay_duration", codecOptional(codecForDuration)) @@ -5199,6 +5207,8 @@ export const codecForTemplateContractFixedOrder = .property("amount", codecOptional(codecForAmountString())) .property("currency", codecOptional(codecForString())) + .property("min_amount", codecOptional(codecForAmountString())) + .property("max_amount", codecOptional(codecForAmountString())) .property("max_pickup_duration", codecOptional(codecForDuration)) .property("minimum_age", codecOptional(codecForNumber())) .property("pay_duration", codecOptional(codecForDuration))