taler-typescript-core

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

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:
Mpackages/taler-util/src/http-client/merchant.ts | 6++++++
Mpackages/taler-util/src/http-client/path-escaping.test.ts | 18++++++++++++++++++
Mpackages/taler-util/src/types-taler-merchant.ts | 11+++++++++++
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()))