commit 817c567b71dd7f68d0e6525178b225160930b3ab
parent 482c6cfddf2f8c2a074efa653dba06c266d64ad0
Author: Florian Dold <dold@taler.net>
Date: Wed, 19 Aug 2026 18:16:21 +0200
taler-util: support expired order filtering
Diffstat:
3 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts
@@ -1823,6 +1823,9 @@ export class TalerMerchantInstanceHttpClient {
if (params.wired !== undefined) {
url.searchParams.set("wired", params.wired ? "YES" : "NO");
}
+ if (params.expired !== undefined) {
+ url.searchParams.set("expired", params.expired ? "YES" : "NO");
+ }
if (params.date && !AbsoluteTime.isNever(params.date)) {
const time = AbsoluteTime.toProtocolTimestamp(params.date);
url.searchParams.set("date_s", String(time.t_s));
@@ -1890,6 +1893,9 @@ export class TalerMerchantInstanceHttpClient {
if (params.wired !== undefined) {
url.searchParams.set("wired", params.wired ? "YES" : "NO");
}
+ if (params.expired !== undefined) {
+ url.searchParams.set("expired", params.expired ? "YES" : "NO");
+ }
if (params.date && !AbsoluteTime.isNever(params.date)) {
const time = AbsoluteTime.toProtocolTimestamp(params.date);
url.searchParams.set("date_s", String(time.t_s));
diff --git a/packages/taler-util/src/http-client/path-escaping.test.ts b/packages/taler-util/src/http-client/path-escaping.test.ts
@@ -100,6 +100,24 @@ test("a hostile order id cannot inject extra path segments", async (t) => {
);
});
+test("order expiration filters are sent to the merchant backend", async () => {
+ const lib = new RecordingHttpLib();
+ const client = new TalerMerchantInstanceHttpClient(
+ "https://merchant.example.com/",
+ lib,
+ );
+ await client
+ .listOrders("secret-token" as any, {
+ paid: false,
+ expired: true,
+ })
+ .catch(() => undefined);
+ assert.ok(lib.lastUrl !== undefined, "no request was made");
+ const url = new URL(lib.lastUrl!);
+ assert.strictEqual(url.searchParams.get("paid"), "NO");
+ assert.strictEqual(url.searchParams.get("expired"), "YES");
+});
+
test("multi-line URL builders escape their path parameters too", async (t) => {
const bank = new RecordingHttpLib();
const bankClient = new TalerCoreBankHttpClient(
diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts
@@ -1588,6 +1588,12 @@ export interface ListOrdersRequestParams {
*/
wired?: boolean;
/**
+ * If set to yes, only return expired orders, if no exclude expired
+ * orders. An order is expired when it is unpaid and its payment deadline
+ * is in the past. Since protocol v37.
+ */
+ expired?: boolean;
+ /**
* At most return the given number of results. Negative
* for descending by row ID, positive for ascending by
* row ID. Default is 20. Since protocol v12.
@@ -2934,6 +2940,10 @@ export interface OrderHistoryEntry {
// When the order was created.
timestamp: Timestamp;
+ // Deadline by which the order must be paid.
+ // Since protocol v37.
+ pay_deadline?: Timestamp;
+
// The amount of money the order is for.
amount: AmountString;
@@ -5056,6 +5066,7 @@ export const codecForOrderHistoryEntry = (): Codec<OrderHistoryEntry> =>
.property("order_id", codecForString())
.property("row_id", codecForNumber())
.property("timestamp", codecForTimestamp)
+ .property("pay_deadline", codecOptional(codecForTimestamp))
.property("amount", codecForAmountString())
.property("refund_amount", codecOptional(codecForAmountString()))
.property("pending_refund_amount", codecOptional(codecForAmountString()))