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:
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))