taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit 8dff335c269adf4b4d7fc0c9ea5e75f098f0801e
parent 678c99c753a2a93ab3bcfc4920cd70edff6281c0
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 25 May 2026 17:13:44 +0200

split up major paivana chapters

Diffstat:
Adrupal-paivana-manual.rst | 27+++++++++++++++++++++++++++
Mindex.rst | 2+-
Apaivana-httpd-manual.rst | 575+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtaler-paivana-manual.rst | 579+------------------------------------------------------------------------------
Awordpress-paivana-manual.rst | 28++++++++++++++++++++++++++++
5 files changed, 636 insertions(+), 575 deletions(-)

diff --git a/drupal-paivana-manual.rst b/drupal-paivana-manual.rst @@ -0,0 +1,27 @@ +.. + This file is part of GNU TALER. + + Copyright (C) 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + + @author Christian Grothoff + +.. _drupal-paivana: + +Drupal integration +================== + +This chapter documents the installation and operation of the +Drupal Paivana module. + +FIXME! diff --git a/index.rst b/index.rst @@ -68,6 +68,7 @@ and overall usage of the different Taler components in text and video formats. taler-merchant-manual taler-merchant-pos-terminal + taler-paivana-manual .. toctree:: :maxdepth: 1 @@ -136,4 +137,3 @@ and overall usage of the different Taler components in text and video formats. :caption: Other genindex - diff --git a/paivana-httpd-manual.rst b/paivana-httpd-manual.rst @@ -0,0 +1,575 @@ +.. + This file is part of GNU TALER. + + Copyright (C) 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + + @author Christian Grothoff + +.. _Paivana-httpd: + +Paivana-httpd +============= + +This chapter documents the installation and operation of the Paivana +reverse proxy ``paivana-httpd``. The reverse proxy sits between the +public Internet and an upstream Web service, intercepting requests +that have not yet been paid for and presenting the client with a +GNU Taler paywall. Once a payment has been confirmed by the +configured GNU Taler merchant backend, ``paivana-httpd`` forwards +subsequent requests of that client to the upstream service. + +The full list of command-line options is documented in +:manpage:`paivana-httpd(1)`; the configuration file is +documented in :manpage:`paivana.conf(5)`. + + +Architecture overview +--------------------- + +``paivana-httpd`` does not implement any payment logic of its own. +Instead, every Paivana deployment combines three components: + +1. **The upstream web service.** This is the existing HTTP service + whose content should be sold (a static website, a cgit service, + a REST API, …). It does not need to be modified to + work with Paivana. +2. **A GNU Taler merchant backend** (``taler-merchant-httpd``). The + merchant backend manages templates, creates orders, talks to one + or more Taler exchanges, and ultimately reports back whether a + given order has been paid. See the + :ref:`Taler Merchant Backend Operator Manual + <taler-merchant-backend-operator-manual>` for full details. +3. **``paivana-httpd`` itself.** This is the reverse proxy that + gates the upstream service. It reads a single + :ref:`paivana.conf <Paivana-Configuration>` configuration file + that points at both the merchant backend and the upstream + service. + +Typically a TLS-terminating reverse proxy (Nginx or Apache) is +deployed in front of ``paivana-httpd`` to handle HTTPS and to route +multiple virtual hosts; see :ref:`Paivana-ReverseProxy` below. + +In normal operation the request flow is: + +:: + + client ──▶ Nginx/Apache (TLS) ──▶ paivana-httpd ──▶ upstream + │ + ▼ + taler-merchant-httpd + │ + ▼ + Taler exchange + + +Installation +------------ + +Installing from source +^^^^^^^^^^^^^^^^^^^^^^ + +The package sources can be found in our +`download directory <http://ftpmirror.gnu.org/taler/>`__. + +GNU Taler components follow the ``MAJOR.MINOR.MICRO`` version +scheme. The general rule for compatibility is that ``MAJOR`` and +``MINOR`` must match across components; exceptions are noted in the +release notes. For example, ``paivana-httpd`` 1.6.x is expected to +work with ``taler-merchant-httpd`` 1.6.x. A ``MAJOR`` version of 0 +indicates experimental development; in that case you should always +run the *latest* releases of every component together. + +The following packages must be installed before compiling +``paivana-httpd``: + +- GNUnet (``libgnunetutil``) matching the Taler release +- GNU Taler exchange libraries (``libtalerexchange``, + ``libtalerutil``) +- GNU Taler merchant client library (``libtalermerchant``) +- GNU Taler HTTP daemon helpers (``libtalermhd``, + ``libtalertemplating``) +- libmicrohttpd, libcurl, libjansson, libgcrypt, zlib + +Build and install with: + +.. code-block:: shell-session + + $ ./bootstrap + $ ./configure --prefix=$PREFIX + $ make + $ sudo make install + + +Installing the binary packages on Debian +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. include:: frags/installing-debian.rst + +To install ``paivana-httpd`` you can now simply run: + +.. code-block:: shell-session + + # apt install paivana-httpd + +The package does not perform any deployment-specific configuration +work; it only sets up the ``paivana-httpd`` system user, the systemd +service and socket units, and installs example configuration +snippets for Nginx and Apache under ``/etc/nginx/sites-available/`` +and ``/etc/apache2/sites-available/``. You still must configure the +HTTP request routing and the Paivana templates as described below. + + +Installing the binary packages on Ubuntu +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. include:: frags/installing-ubuntu.rst + +To install ``paivana-httpd``, run: + +.. code-block:: shell-session + + # apt install paivana-httpd + +As on Debian, the package does not perform any deployment-specific +configuration work. + + +.. _Paivana-Configuration: + +Configuring paivana-httpd +------------------------- + +The main configuration file is ``/etc/paivana/paivana.conf``. Its +syntax follows the standard GNUnet configuration file format and is +documented in full in :manpage:`paivana.conf(5)`. Default values +shipped with the package live under +``/usr/share/paivana/config.d/``; values in ``paivana.conf`` +override those defaults. + +All Paivana-specific keys live in the ``[paivana]`` section. At a +minimum, the file must specify three things: + +- where ``paivana-httpd`` should listen for incoming requests + (``SERVE``, ``UNIXPATH`` / ``PORT``); +- where it should forward paid requests to + (``DESTINATION_BASE_URL``); +- how it should reach the merchant backend + (``MERCHANT_BACKEND_URL`` and ``MERCHANT_ACCESS_TOKEN``). + +A typical configuration that listens on a UNIX domain socket +managed by systemd and forwards to a local upstream server looks +like this: + +.. code-block:: ini + + [paivana] + # Listen on the socket provided by paivana-httpd.socket. + SERVE = unix + UNIXPATH = /run/paivana/httpd/paivana-http.sock + UNIXPATH_MODE = 660 + + # Public base URL of this paywall as seen by clients. + # Used when the Host/X-Forwarded-Host headers are unavailable. + BASE_URL = https://paywall.example.com/ + + # Upstream service that gets proxied after payment. + DESTINATION_BASE_URL = http://127.0.0.1:8080/ + + # Merchant backend used to create and verify orders. + MERCHANT_BACKEND_URL = http://localhost:9966/ + MERCHANT_ACCESS_TOKEN = secret-token:CHANGE-ME + + # Stable secret used to MAC the access cookie. + # If unset, a random value is generated at every startup, + # invalidating all previously issued cookies. + SECRET = please-change-this-to-a-long-random-value + + # Resources that should never trigger the paywall, e.g. + # logos, stylesheets or favicons. + WHITELIST = ^/(favicon\.ico|assets/.*|robots\.txt)$ + +The exhaustive list of supported keys (``SERVE``, ``PORT``, +``BIND_TO``, ``UNIXPATH``, ``UNIXPATH_MODE``, ``BASE_URL``, +``DESTINATION_BASE_URL``, ``MERCHANT_BACKEND_URL``, +``MERCHANT_BACKEND_UNIX_PATH``, ``MERCHANT_ACCESS_TOKEN``, +``SECRET``, ``WHITELIST``) is documented in +:manpage:`paivana.conf(5)`. + +If you reach the merchant backend over a UNIX domain socket on the +same host (recommended for a single-machine deployment), replace +the ``MERCHANT_BACKEND_URL`` block with: + +.. code-block:: ini + + MERCHANT_BACKEND_URL = http://localhost/ + MERCHANT_BACKEND_UNIX_PATH = /run/taler-merchant/merchant.sock + +.. note:: + + ``MERCHANT_ACCESS_TOKEN`` and ``SECRET`` are sensitive values. + Make sure ``paivana.conf`` is only readable by the + ``paivana-httpd`` user. The Debian package installs the file + accordingly. + +When ``paivana-httpd`` runs behind a trusted reverse proxy +(Nginx/Apache), pass ``-f`` / ``--respect-forwarded-headers`` in the +systemd unit's ``ExecStart=`` so the real client address is taken +from ``X-Forwarded-For``. See :manpage:`paivana-httpd(1)` for the +remaining command-line flags (in particular ``-g`` to require only +a single payment per site and ``-n`` to disable the paywall for +debugging). + + +Starting and stopping the service +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Debian/Ubuntu package ships a socket-activated systemd unit. +After editing ``/etc/paivana/paivana.conf`` enable and start it: + +.. code-block:: shell-session + + # systemctl enable --now paivana-httpd.socket + # systemctl status paivana-httpd + +The socket listens on ``/run/paivana/httpd/paivana-http.sock`` with +group ``www-data``, which lets a co-located Nginx or Apache talk to +the daemon without granting it broader filesystem access. Logs are +sent to the journal: + +.. code-block:: shell-session + + # journalctl -u paivana-httpd -f + + +.. _Paivana-Templates: + +Configuring Paivana templates +----------------------------- + +``paivana-httpd`` does not store any per-site pricing or URL-matching rules +itself. Instead, all rules are expressed as :ref:`merchant templates +<template>` of type ``paivana`` in the merchant backend. When +``paivana-httpd`` starts up it asks the merchant backend for every template +configured for the instance identified by ``MERCHANT_BACKEND_URL`` and uses +the ``website_regex`` field of each template to decide which template (and +therefore which payment options) applies to an incoming request URL. + +The corresponding REST API is documented in detail in the +:ref:`Merchant Backend HTTP API <merchant-api>`; see in particular +the +`POST /private/templates +<https://docs.taler.net/core/api-merchant.html#post--private-templates>`__ +endpoint and the +:ts:type:`TemplateContractPaivana` definition. + +Prerequisites +^^^^^^^^^^^^^ + +Before creating a template you need: + +- a running ``taler-merchant-httpd`` (see the + :ref:`Launching-the-backend` section of the merchant manual); +- a merchant :ref:`instance <Instance-setup>` with at least one + configured :ref:`bank account <instance-bank-account>`; +- the access token of that instance (used as + ``MERCHANT_ACCESS_TOKEN`` in ``paivana.conf``). + +In the examples below we assume the merchant backend is reachable +at ``http://localhost:9966/``, the default instance is ``default``, +its access token is ``secret-token:sandbox`` and the currency is +``KUDOS``. Adjust the URLs, tokens and amounts to match your +deployment. The +`src/backend/test.sh +<https://git.taler.net/paivana.git/tree/src/backend/test.sh>`__ +script that ships with Paivana sets up exactly this minimal +configuration and is a good starting point for experimentation. + +Creating a single global template +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The simplest Paivana setup uses one template that matches every +URL on the site and charges a fixed price. This is the +configuration created by ``src/backend/test.sh``: + +.. code-block:: bash + + $ curl -X POST http://localhost:9966/private/templates \ + -H 'Authorization: Bearer secret-token:sandbox' \ + -H 'Content-Type: application/json' \ + -d '{ + "template_id": "paivana", + "template_description": "A Paivana template", + "template_contract": { + "template_type": "paivana", + "summary": "Access to example.com", + "website_regex": ".*", + "choices": [ { "amount": "KUDOS:1" } ] + } + }' + +The ``template_type`` must be ``"paivana"``: this allows +``paivana-httpd`` to pick the template up at startup and +also enables some required logic in the merchant backend. The +``website_regex`` is a POSIX extended regular expression that is +matched against the request URL; ``.*`` covers everything. Each +entry in ``choices`` describes one way the client may pay and is an +:ts:type:`OrderChoice` object (so the paywall can also support +the use of subscription tokens, discount coupons, etc.). + +A successful create returns HTTP ``204 No Content``. After +creating the template, (re)start ``paivana-httpd`` so that it +re-reads the template list: + +.. code-block:: shell-session + + # systemctl restart paivana-httpd + +Multiple templates with URL-specific pricing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When a single site contains content with different prices, define one template +per price bucket and use ``website_regex`` to scope each template to the +matching URLs. When several templates match the same URL ``paivana-httpd`` +picks the first one if finds that matches. Be careful: if multiple templates +match a URL, the result is non-deterministic! + +For example, a news site might charge 2 KUDOS for premium articles +and 50 cents (``KUDOS:0.5``) for standard articles: + +.. code-block:: bash + + $ curl -X POST http://localhost:9966/private/templates \ + -H 'Authorization: Bearer secret-token:sandbox' \ + -H 'Content-Type: application/json' \ + -d '{ + "template_id": "premium", + "template_description": "Premium long-form articles", + "template_contract": { + "template_type": "paivana", + "summary": "Premium article on example.com", + "website_regex": "^/premium/.*", + "choices": [ { "amount": "KUDOS:2" } ] + } + }' + + $ curl -X POST http://localhost:9966/private/templates \ + -H 'Authorization: Bearer secret-token:sandbox' \ + -H 'Content-Type: application/json' \ + -d '{ + "template_id": "default", + "template_description": "Standard articles", + "template_contract": { + "template_type": "paivana", + "summary": "Standard article on example.com", + "website_regex": "^/standard/.*", + "choices": [ { "amount": "KUDOS:0.5" } ] + } + }' + +Offering multiple payment options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``choices`` array lets a single template offer several mutually exclusive +ways to pay. A common pattern is to accept either a cash payment or to sell a +subscription; the wallet shows both options and the customer picks one. The +third option, where the customer already has a subscription, will be used +automatically by the wallet for subscribers and the customer will not even +have to click to bypass the paywall as a subscriber. See the merchant manual +for the details of :ref:`OrderChoice <template-choice>` objects. + +.. code-block:: bash + + $ curl -X POST http://localhost:9966/private/templates \ + -H 'Authorization: Bearer secret-token:sandbox' \ + -H 'Content-Type: application/json' \ + -d '{ + "template_id": "article", + "template_description": "Single article, paid or via subscription", + "template_contract": { + "template_type": "paivana", + "summary": "Article on example.com", + "website_regex": ".*", + "choices": [ + { "amount": "KUDOS:1", + "description": "Pay per article" }, + { "amount": "KUDOS:100", + "description": "Buy subscription", + "outputs": [ { "token": "monthly-subscription" } ] }, + { "amount": "KUDOS:0", + "description": "Use my subscription", + "inputs": [ { "token": "monthly-subscription" } ], + "outputs": [ { "token": "monthly-subscription" } ] } + ] + } + }' + +Managing templates +^^^^^^^^^^^^^^^^^^ + +Templates can be listed, updated and deleted through the merchant +backend's REST API or through the merchant backend SPA at +``$MERCHANT_BACKEND_URL/``. See the merchant manual section on +:ref:`templates <template>` for details, and the API reference for +the relevant endpoints: + +- `GET /private/templates + <https://docs.taler.net/core/api-merchant.html#get--private-templates>`__ — + list all templates of the instance; +- `PATCH /private/templates/$TEMPLATE_ID + <https://docs.taler.net/core/api-merchant.html#patch--private-templates-$TEMPLATE_ID>`__ — + update a template; +- `DELETE /private/templates/$TEMPLATE_ID + <https://docs.taler.net/core/api-merchant.html#delete--private-templates-$TEMPLATE_ID>`__ — + remove a template. + +After any change, restart ``paivana-httpd`` so the new template +list takes effect. + + +.. _Paivana-ReverseProxy: + +Reverse proxy configuration +--------------------------- + +``paivana-httpd`` itself speaks plain HTTP on a UNIX socket (or a +local TCP port). In production it is often run behind an Internet-facing +reverse proxy that terminates TLS and forwards requests to the +Paivana socket. This section gives minimal working examples for +both Nginx and Apache. The same approach is used for the merchant +backend; see the merchant manual's +:ref:`reverse-proxy-configuration` section for additional +discussion. + +The examples assume the public domain is ``example.com``, +that ``paivana-httpd`` is socket-activated by the shipped +``paivana-httpd.socket`` unit (so its listening socket lives at +``/run/paivana/httpd/paivana-http.sock``) and that TLS termination +happens at the reverse proxy. + +.. tab-set:: + + .. tab-item:: Nginx + + Place the snippet below in + ``/etc/nginx/sites-available/example.com`` (the + Debian package installs a starter template under + ``/etc/nginx/sites-available/paivana``), then enable it via + ``ln -s ../sites-available/example.com + /etc/nginx/sites-enabled/`` and reload Nginx + (``systemctl reload nginx``). + + .. code-block:: nginx + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name example.com; + + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; + + location / { + proxy_pass http://unix:/run/paivana/httpd/paivana-http.sock; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto https; + } + } + + server { + listen 80; + listen [::]:80; + server_name example.com; + return 301 https://$host$request_uri; + } + + Make sure ``paivana-httpd`` is started with + ``--respect-forwarded-headers`` (see + :manpage:`paivana-httpd(1)`) so the ``X-Forwarded-For`` + header set above is honoured. + + .. tab-item:: Apache + + Enable the required modules once: + + .. code-block:: shell-session + + # a2enmod proxy proxy_http headers ssl + # systemctl reload apache2 + + Then drop the following into + ``/etc/apache2/sites-available/example.com.conf`` + (the Debian package installs a starter template at + ``/etc/apache2/sites-available/paivana.conf``), enable it + with ``a2ensite example.com`` and reload Apache. + + .. code-block:: apacheconf + + <VirtualHost *:80> + ServerName example.com + Redirect permanent / https://example.com/ + </VirtualHost> + + <VirtualHost *:443> + ServerName example.com + + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem + + <Location "/"> + ProxyPass "unix:/run/paivana/httpd/paivana-http.sock|http://example.com/" + ProxyPassReverse "unix:/run/paivana/httpd/paivana-http.sock|http://example.com/" + RequestHeader set X-Forwarded-Proto "https" + RequestHeader set X-Forwarded-Host "example.com" + </Location> + </VirtualHost> + + As with Nginx, run ``paivana-httpd`` with + ``--respect-forwarded-headers`` so that the client IP is + taken from ``X-Forwarded-For``. + +If you operate both Paivana and the merchant backend on the same +host, you typically expose them under two different hostnames (e.g. +``example.com`` and ``backend.example.com``); the merchant +backend must *never* be proxied through ``paivana-httpd``, only +the upstream content service should be. + + +Verifying the setup +------------------- + +After completing the steps above, a quick smoke test is to request +a paywalled URL with ``curl``: + +.. code-block:: shell-session + + $ curl -i https://example.com/some-article + +An unpaid request should return ``HTTP/1.1 402 Payment Required`` together +with a Taler-formatted paywall body containing the ``taler://pay/...`` URI of +the freshly created order. Paying that order with any GNU Taler wallet (see +the `Wallet documentation <https://docs.taler.net/wallet/>`__) and +re-requesting the URL from the same client should then yield the upstream +content unchanged. If the page is run in a browser, the client-side +JavaScript should automatically trigger the required reload of the page after +the wallet made the payment. + +For interactive debugging, ``paivana-httpd -n`` disables the +paywall and turns the daemon into a transparent reverse proxy; +this is useful to confirm that the network plumbing to the +upstream service works before involving the merchant backend. +See :manpage:`paivana-httpd(1)` for the other runtime flags. diff --git a/taler-paivana-manual.rst b/taler-paivana-manual.rst @@ -14,7 +14,8 @@ You should have received a copy of the GNU Affero General Public License along with TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> - @author Martin Schanzenbach + @author Christian Grothoff + Paivana Operator Manual ####################### @@ -78,578 +79,8 @@ and configured to process orders. When setting up the respective Paivana service, you must have the base URL, username and password of the selected merchant backend at hand. +.. include:: paivana-httpd-manual.rst -.. _Paivana-httpd: - -Paivana-httpd -============= - -This chapter documents the installation and operation of the Paivana -reverse proxy ``paivana-httpd``. The reverse proxy sits between the -public Internet and an upstream Web service, intercepting requests -that have not yet been paid for and presenting the client with a -GNU Taler paywall. Once a payment has been confirmed by the -configured GNU Taler merchant backend, ``paivana-httpd`` forwards -subsequent requests of that client to the upstream service. - -The full list of command-line options is documented in -:manpage:`paivana-httpd(1)`; the configuration file is -documented in :manpage:`paivana.conf(5)`. - - -Architecture overview ---------------------- - -``paivana-httpd`` does not implement any payment logic of its own. -Instead, every Paivana deployment combines three components: - -1. **The upstream web service.** This is the existing HTTP service - whose content should be sold (a static website, a cgit service, - a REST API, …). It does not need to be modified to - work with Paivana. -2. **A GNU Taler merchant backend** (``taler-merchant-httpd``). The - merchant backend manages templates, creates orders, talks to one - or more Taler exchanges, and ultimately reports back whether a - given order has been paid. See the - :ref:`Taler Merchant Backend Operator Manual - <taler-merchant-backend-operator-manual>` for full details. -3. **``paivana-httpd`` itself.** This is the reverse proxy that - gates the upstream service. It reads a single - :ref:`paivana.conf <Paivana-Configuration>` configuration file - that points at both the merchant backend and the upstream - service. - -Typically a TLS-terminating reverse proxy (Nginx or Apache) is -deployed in front of ``paivana-httpd`` to handle HTTPS and to route -multiple virtual hosts; see :ref:`Paivana-ReverseProxy` below. - -In normal operation the request flow is: - -:: - - client ──▶ Nginx/Apache (TLS) ──▶ paivana-httpd ──▶ upstream - │ - ▼ - taler-merchant-httpd - │ - ▼ - Taler exchange - - -Installation ------------- - -Installing from source -^^^^^^^^^^^^^^^^^^^^^^ - -The package sources can be found in our -`download directory <http://ftpmirror.gnu.org/taler/>`__. - -GNU Taler components follow the ``MAJOR.MINOR.MICRO`` version -scheme. The general rule for compatibility is that ``MAJOR`` and -``MINOR`` must match across components; exceptions are noted in the -release notes. For example, ``paivana-httpd`` 1.6.x is expected to -work with ``taler-merchant-httpd`` 1.6.x. A ``MAJOR`` version of 0 -indicates experimental development; in that case you should always -run the *latest* releases of every component together. - -The following packages must be installed before compiling -``paivana-httpd``: - -- GNUnet (``libgnunetutil``) matching the Taler release -- GNU Taler exchange libraries (``libtalerexchange``, - ``libtalerutil``) -- GNU Taler merchant client library (``libtalermerchant``) -- GNU Taler HTTP daemon helpers (``libtalermhd``, - ``libtalertemplating``) -- libmicrohttpd, libcurl, libjansson, libgcrypt, zlib - -Build and install with: - -.. code-block:: shell-session - - $ ./bootstrap - $ ./configure --prefix=$PREFIX - $ make - $ sudo make install - - -Installing the binary packages on Debian -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. include:: frags/installing-debian.rst - -To install ``paivana-httpd`` you can now simply run: - -.. code-block:: shell-session - - # apt install paivana-httpd - -The package does not perform any deployment-specific configuration -work; it only sets up the ``paivana-httpd`` system user, the systemd -service and socket units, and installs example configuration -snippets for Nginx and Apache under ``/etc/nginx/sites-available/`` -and ``/etc/apache2/sites-available/``. You still must configure the -HTTP request routing and the Paivana templates as described below. - - -Installing the binary packages on Ubuntu -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. include:: frags/installing-ubuntu.rst - -To install ``paivana-httpd``, run: - -.. code-block:: shell-session - - # apt install paivana-httpd - -As on Debian, the package does not perform any deployment-specific -configuration work. - - -.. _Paivana-Configuration: - -Configuring paivana-httpd -------------------------- - -The main configuration file is ``/etc/paivana/paivana.conf``. Its -syntax follows the standard GNUnet configuration file format and is -documented in full in :manpage:`paivana.conf(5)`. Default values -shipped with the package live under -``/usr/share/paivana/config.d/``; values in ``paivana.conf`` -override those defaults. - -All Paivana-specific keys live in the ``[paivana]`` section. At a -minimum, the file must specify three things: - -- where ``paivana-httpd`` should listen for incoming requests - (``SERVE``, ``UNIXPATH`` / ``PORT``); -- where it should forward paid requests to - (``DESTINATION_BASE_URL``); -- how it should reach the merchant backend - (``MERCHANT_BACKEND_URL`` and ``MERCHANT_ACCESS_TOKEN``). - -A typical configuration that listens on a UNIX domain socket -managed by systemd and forwards to a local upstream server looks -like this: - -.. code-block:: ini - - [paivana] - # Listen on the socket provided by paivana-httpd.socket. - SERVE = unix - UNIXPATH = /run/paivana/httpd/paivana-http.sock - UNIXPATH_MODE = 660 - - # Public base URL of this paywall as seen by clients. - # Used when the Host/X-Forwarded-Host headers are unavailable. - BASE_URL = https://paywall.example.com/ - - # Upstream service that gets proxied after payment. - DESTINATION_BASE_URL = http://127.0.0.1:8080/ - - # Merchant backend used to create and verify orders. - MERCHANT_BACKEND_URL = http://localhost:9966/ - MERCHANT_ACCESS_TOKEN = secret-token:CHANGE-ME - - # Stable secret used to MAC the access cookie. - # If unset, a random value is generated at every startup, - # invalidating all previously issued cookies. - SECRET = please-change-this-to-a-long-random-value - - # Resources that should never trigger the paywall, e.g. - # logos, stylesheets or favicons. - WHITELIST = ^/(favicon\.ico|assets/.*|robots\.txt)$ - -The exhaustive list of supported keys (``SERVE``, ``PORT``, -``BIND_TO``, ``UNIXPATH``, ``UNIXPATH_MODE``, ``BASE_URL``, -``DESTINATION_BASE_URL``, ``MERCHANT_BACKEND_URL``, -``MERCHANT_BACKEND_UNIX_PATH``, ``MERCHANT_ACCESS_TOKEN``, -``SECRET``, ``WHITELIST``) is documented in -:manpage:`paivana.conf(5)`. - -If you reach the merchant backend over a UNIX domain socket on the -same host (recommended for a single-machine deployment), replace -the ``MERCHANT_BACKEND_URL`` block with: - -.. code-block:: ini - - MERCHANT_BACKEND_URL = http://localhost/ - MERCHANT_BACKEND_UNIX_PATH = /run/taler-merchant/merchant.sock - -.. note:: - - ``MERCHANT_ACCESS_TOKEN`` and ``SECRET`` are sensitive values. - Make sure ``paivana.conf`` is only readable by the - ``paivana-httpd`` user. The Debian package installs the file - accordingly. - -When ``paivana-httpd`` runs behind a trusted reverse proxy -(Nginx/Apache), pass ``-f`` / ``--respect-forwarded-headers`` in the -systemd unit's ``ExecStart=`` so the real client address is taken -from ``X-Forwarded-For``. See :manpage:`paivana-httpd(1)` for the -remaining command-line flags (in particular ``-g`` to require only -a single payment per site and ``-n`` to disable the paywall for -debugging). - - -Starting and stopping the service -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The Debian/Ubuntu package ships a socket-activated systemd unit. -After editing ``/etc/paivana/paivana.conf`` enable and start it: - -.. code-block:: shell-session - - # systemctl enable --now paivana-httpd.socket - # systemctl status paivana-httpd - -The socket listens on ``/run/paivana/httpd/paivana-http.sock`` with -group ``www-data``, which lets a co-located Nginx or Apache talk to -the daemon without granting it broader filesystem access. Logs are -sent to the journal: - -.. code-block:: shell-session - - # journalctl -u paivana-httpd -f - - -.. _Paivana-Templates: - -Configuring Paivana templates ------------------------------ - -``paivana-httpd`` does not store any per-site pricing or URL-matching rules -itself. Instead, all rules are expressed as :ref:`merchant templates -<template>` of type ``paivana`` in the merchant backend. When -``paivana-httpd`` starts up it asks the merchant backend for every template -configured for the instance identified by ``MERCHANT_BACKEND_URL`` and uses -the ``website_regex`` field of each template to decide which template (and -therefore which payment options) applies to an incoming request URL. - -The corresponding REST API is documented in detail in the -:ref:`Merchant Backend HTTP API <merchant-api>`; see in particular -the -`POST /private/templates -<https://docs.taler.net/core/api-merchant.html#post--private-templates>`__ -endpoint and the -:ts:type:`TemplateContractPaivana` definition. - -Prerequisites -^^^^^^^^^^^^^ - -Before creating a template you need: - -- a running ``taler-merchant-httpd`` (see the - :ref:`Launching-the-backend` section of the merchant manual); -- a merchant :ref:`instance <Instance-setup>` with at least one - configured :ref:`bank account <instance-bank-account>`; -- the access token of that instance (used as - ``MERCHANT_ACCESS_TOKEN`` in ``paivana.conf``). - -In the examples below we assume the merchant backend is reachable -at ``http://localhost:9966/``, the default instance is ``default``, -its access token is ``secret-token:sandbox`` and the currency is -``KUDOS``. Adjust the URLs, tokens and amounts to match your -deployment. The -`src/backend/test.sh -<https://git.taler.net/paivana.git/tree/src/backend/test.sh>`__ -script that ships with Paivana sets up exactly this minimal -configuration and is a good starting point for experimentation. - -Creating a single global template -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The simplest Paivana setup uses one template that matches every -URL on the site and charges a fixed price. This is the -configuration created by ``src/backend/test.sh``: - -.. code-block:: bash - - $ curl -X POST http://localhost:9966/private/templates \ - -H 'Authorization: Bearer secret-token:sandbox' \ - -H 'Content-Type: application/json' \ - -d '{ - "template_id": "paivana", - "template_description": "A Paivana template", - "template_contract": { - "template_type": "paivana", - "summary": "Access to example.com", - "website_regex": ".*", - "choices": [ { "amount": "KUDOS:1" } ] - } - }' - -The ``template_type`` must be ``"paivana"``: this allows -``paivana-httpd`` to pick the template up at startup and -also enables some required logic in the merchant backend. The -``website_regex`` is a POSIX extended regular expression that is -matched against the request URL; ``.*`` covers everything. Each -entry in ``choices`` describes one way the client may pay and is an -:ts:type:`OrderChoice` object (so the paywall can also support -the use of subscription tokens, discount coupons, etc.). - -A successful create returns HTTP ``204 No Content``. After -creating the template, (re)start ``paivana-httpd`` so that it -re-reads the template list: - -.. code-block:: shell-session - - # systemctl restart paivana-httpd - -Multiple templates with URL-specific pricing -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When a single site contains content with different prices, define one template -per price bucket and use ``website_regex`` to scope each template to the -matching URLs. When several templates match the same URL ``paivana-httpd`` -picks the first one if finds that matches. Be careful: if multiple templates -match a URL, the result is non-deterministic! - -For example, a news site might charge 2 KUDOS for premium articles -and 50 cents (``KUDOS:0.5``) for standard articles: - -.. code-block:: bash - - $ curl -X POST http://localhost:9966/private/templates \ - -H 'Authorization: Bearer secret-token:sandbox' \ - -H 'Content-Type: application/json' \ - -d '{ - "template_id": "premium", - "template_description": "Premium long-form articles", - "template_contract": { - "template_type": "paivana", - "summary": "Premium article on example.com", - "website_regex": "^/premium/.*", - "choices": [ { "amount": "KUDOS:2" } ] - } - }' - - $ curl -X POST http://localhost:9966/private/templates \ - -H 'Authorization: Bearer secret-token:sandbox' \ - -H 'Content-Type: application/json' \ - -d '{ - "template_id": "default", - "template_description": "Standard articles", - "template_contract": { - "template_type": "paivana", - "summary": "Standard article on example.com", - "website_regex": "^/standard/.*", - "choices": [ { "amount": "KUDOS:0.5" } ] - } - }' - -Offering multiple payment options -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The ``choices`` array lets a single template offer several mutually exclusive -ways to pay. A common pattern is to accept either a cash payment or to sell a -subscription; the wallet shows both options and the customer picks one. The -third option, where the customer already has a subscription, will be used -automatically by the wallet for subscribers and the customer will not even -have to click to bypass the paywall as a subscriber. See the merchant manual -for the details of :ref:`OrderChoice <template-choice>` objects. - -.. code-block:: bash - - $ curl -X POST http://localhost:9966/private/templates \ - -H 'Authorization: Bearer secret-token:sandbox' \ - -H 'Content-Type: application/json' \ - -d '{ - "template_id": "article", - "template_description": "Single article, paid or via subscription", - "template_contract": { - "template_type": "paivana", - "summary": "Article on example.com", - "website_regex": ".*", - "choices": [ - { "amount": "KUDOS:1", - "description": "Pay per article" }, - { "amount": "KUDOS:100", - "description": "Buy subscription", - "outputs": [ { "token": "monthly-subscription" } ] }, - { "amount": "KUDOS:0", - "description": "Use my subscription", - "inputs": [ { "token": "monthly-subscription" } ], - "outputs": [ { "token": "monthly-subscription" } ] } - ] - } - }' - -Managing templates -^^^^^^^^^^^^^^^^^^ - -Templates can be listed, updated and deleted through the merchant -backend's REST API or through the merchant backend SPA at -``$MERCHANT_BACKEND_URL/``. See the merchant manual section on -:ref:`templates <template>` for details, and the API reference for -the relevant endpoints: - -- `GET /private/templates - <https://docs.taler.net/core/api-merchant.html#get--private-templates>`__ — - list all templates of the instance; -- `PATCH /private/templates/$TEMPLATE_ID - <https://docs.taler.net/core/api-merchant.html#patch--private-templates-$TEMPLATE_ID>`__ — - update a template; -- `DELETE /private/templates/$TEMPLATE_ID - <https://docs.taler.net/core/api-merchant.html#delete--private-templates-$TEMPLATE_ID>`__ — - remove a template. - -After any change, restart ``paivana-httpd`` so the new template -list takes effect. - - -.. _Paivana-ReverseProxy: - -Reverse proxy configuration ---------------------------- - -``paivana-httpd`` itself speaks plain HTTP on a UNIX socket (or a -local TCP port). In production it is often run behind an Internet-facing -reverse proxy that terminates TLS and forwards requests to the -Paivana socket. This section gives minimal working examples for -both Nginx and Apache. The same approach is used for the merchant -backend; see the merchant manual's -:ref:`reverse-proxy-configuration` section for additional -discussion. - -The examples assume the public domain is ``example.com``, -that ``paivana-httpd`` is socket-activated by the shipped -``paivana-httpd.socket`` unit (so its listening socket lives at -``/run/paivana/httpd/paivana-http.sock``) and that TLS termination -happens at the reverse proxy. - -.. tab-set:: - - .. tab-item:: Nginx - - Place the snippet below in - ``/etc/nginx/sites-available/example.com`` (the - Debian package installs a starter template under - ``/etc/nginx/sites-available/paivana``), then enable it via - ``ln -s ../sites-available/example.com - /etc/nginx/sites-enabled/`` and reload Nginx - (``systemctl reload nginx``). - - .. code-block:: nginx - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name example.com; - - ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; - - location / { - proxy_pass http://unix:/run/paivana/httpd/paivana-http.sock; - proxy_redirect off; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Proto https; - } - } - - server { - listen 80; - listen [::]:80; - server_name example.com; - return 301 https://$host$request_uri; - } - - Make sure ``paivana-httpd`` is started with - ``--respect-forwarded-headers`` (see - :manpage:`paivana-httpd(1)`) so the ``X-Forwarded-For`` - header set above is honoured. - - .. tab-item:: Apache - - Enable the required modules once: - - .. code-block:: shell-session - - # a2enmod proxy proxy_http headers ssl - # systemctl reload apache2 - - Then drop the following into - ``/etc/apache2/sites-available/example.com.conf`` - (the Debian package installs a starter template at - ``/etc/apache2/sites-available/paivana.conf``), enable it - with ``a2ensite example.com`` and reload Apache. - - .. code-block:: apacheconf - - <VirtualHost *:80> - ServerName example.com - Redirect permanent / https://example.com/ - </VirtualHost> - - <VirtualHost *:443> - ServerName example.com - - SSLEngine on - SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem - SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem - - <Location "/"> - ProxyPass "unix:/run/paivana/httpd/paivana-http.sock|http://example.com/" - ProxyPassReverse "unix:/run/paivana/httpd/paivana-http.sock|http://example.com/" - RequestHeader set X-Forwarded-Proto "https" - RequestHeader set X-Forwarded-Host "example.com" - </Location> - </VirtualHost> - - As with Nginx, run ``paivana-httpd`` with - ``--respect-forwarded-headers`` so that the client IP is - taken from ``X-Forwarded-For``. - -If you operate both Paivana and the merchant backend on the same -host, you typically expose them under two different hostnames (e.g. -``example.com`` and ``backend.example.com``); the merchant -backend must *never* be proxied through ``paivana-httpd``, only -the upstream content service should be. - - -Verifying the setup -------------------- - -After completing the steps above, a quick smoke test is to request -a paywalled URL with ``curl``: - -.. code-block:: shell-session - - $ curl -i https://example.com/some-article - -An unpaid request should return ``HTTP/1.1 402 Payment Required`` together -with a Taler-formatted paywall body containing the ``taler://pay/...`` URI of -the freshly created order. Paying that order with any GNU Taler wallet (see -the `Wallet documentation <https://docs.taler.net/wallet/>`__) and -re-requesting the URL from the same client should then yield the upstream -content unchanged. If the page is run in a browser, the client-side -JavaScript should automatically trigger the required reload of the page after -the wallet made the payment. - -For interactive debugging, ``paivana-httpd -n`` disables the -paywall and turns the daemon into a transparent reverse proxy; -this is useful to confirm that the network plumbing to the -upstream service works before involving the merchant backend. -See :manpage:`paivana-httpd(1)` for the other runtime flags. - - -Drupal integration -================== - -This chapter documents the installation and operation of the -Drupal Paivana module. - -FIXME! - -Wordpress integration -===================== - -This chapter documents the installation and operation of the -Wordpress Paivana module. +.. include:: drupal-paivana-manual.rst -FIXME! +.. include:: wordpress-paivana-manual.rst diff --git a/wordpress-paivana-manual.rst b/wordpress-paivana-manual.rst @@ -0,0 +1,28 @@ +.. + This file is part of GNU TALER. + + Copyright (C) 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + + @author Christian Grothoff + +.. _wordpress-paivana: + + +Wordpress integration +===================== + +This chapter documents the installation and operation of the +Wordpress Paivana module. + +FIXME!