commit cc2d4aa96753b7cbf63175a06ae1c493a3e60466
parent 7ce11109634fce795c3ccf0736b73fbe989036cc
Author: Florian Dold <dold@taler.net>
Date: Mon, 7 Sep 2026 13:48:58 +0200
merchant docs: paivana clarifications
Issue: https://bugs.taler.net/n/11443
Diffstat:
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/core/api-merchant.rst b/core/api-merchant.rst
@@ -1444,8 +1444,10 @@ open or deferred.
// How long will customers have to access / read / pick-up
// the resource they are buying? Will turn into
- // max_pickup_time in the contract. Optional, if not given
- // the duration is forever.
+ // max_pickup_time in the contract for every template type,
+ // measured from order creation (not from payment or a repeat visit).
+ // Optional; if omitted or "forever", access has no deadline.
+ // Zero gives an immediately expired access window.
// Since protocol **v29**.
max_pickup_duration?: RelativeTime;
@@ -1697,8 +1699,9 @@ and basically present (or optional) all the time.
// If a non-unique fulfillment URL is used, a customer can only
// buy the order once and will be redirected to a previous purchase
// when trying to buy an order with the same fulfillment URL a second
- // time. This is useful for digital goods that a customer only needs
- // to buy once but should be able to repeatedly download.
+ // time, while the previous purchase's max_pickup_time still permits
+ // access. This is useful for digital goods that a customer should
+ // be able to repeatedly download during the purchased access period.
//
// For orders where the customer is expected to be able to make
// repeated purchases (for equivalent goods), the fulfillment URL
@@ -1773,7 +1776,10 @@ and basically present (or optional) all the time.
// Latest time until which the good or service specified in the
// contract may be picked up by the customer. This is usually
// for digital goods where the customer has a finite window
- // for downloading the resource(s).
+ // for downloading the resource(s). Absent or "never" means unlimited.
+ // Once this time is reached, wallets must not reuse the purchase to
+ // satisfy a new order with the same fulfillment_url. A new payment
+ // requires the customer's confirmation.
max_pickup_time?: Timestamp;
}
diff --git a/design-documents/076-paywall-proxy.rst b/design-documents/076-paywall-proxy.rst
@@ -192,6 +192,20 @@ Steps:
which is what stops a client from buying five minutes of access and
minting itself a cookie valid for a year.
+ For repeat visits, the wallet may replay an earlier paid order only if
+ its access window is still open and its ``max_pickup_time`` covers the
+ session's requested ``expiration``. An absent or ``never`` deadline is
+ unlimited. A repeat visit does not extend the paid access period.
+
+ When the wallet itself constructs the Paivana session, it can reuse
+ remaining access by capping ``expiration`` at the earlier order's
+ ``max_pickup_time`` **before** computing the session ID. The same capped
+ expiration must be used when redeeming the order for a cookie. A session
+ constructed by a browser already binds the expiration and nonce; the
+ wallet cannot change that expiration. If the previous order cannot cover
+ it, the wallet offers a new purchase requiring confirmation. After the
+ old access window expires, a new purchase is required in either flow.
+
If so, paivana-httpd issues the Paivana cookie described above, with
``Max-Age`` derived from ``expiration``, and redirects to the
``{website}``.