[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-docs] branch master updated (12a3571 -> de704e3)

From: gnunet
Subject: [taler-docs] branch master updated (12a3571 -> de704e3)
Date: Sat, 07 Nov 2020 00:49:06 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository docs.

    from 12a3571  some ideas
     new 1e36811  rework intro
     new 655e5eb  Merge branch 'master' of git+ssh://
     new de704e3  work on merchant tutorial update, unfinished

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.

Summary of changes:
 taler-merchant-api-tutorial.rst | 332 +++++++++++++++++++---------------------
 taler-merchant-manual.rst       |   4 +-
 2 files changed, 158 insertions(+), 178 deletions(-)

diff --git a/taler-merchant-api-tutorial.rst b/taler-merchant-api-tutorial.rst
index 823a675..1449c9f 100644
--- a/taler-merchant-api-tutorial.rst
+++ b/taler-merchant-api-tutorial.rst
@@ -40,8 +40,12 @@ regulation (such as GDPR).
 About this tutorial
-This tutorial addresses how to process payments using the GNU Taler
-merchant Backend. This chapter explains some basic concepts. In the
+This tutorial addresses how to process payments using the GNU Taler merchant
+Backend.  The audience for this tutorial are *developers* of merchants (such
+as Web shops) that are working on integrating GNU Taler with the
+customer-facing Frontend and the staff-facing Backoffice.
+This chapter explains some basic concepts. In the
 second chapter, you will learn how to do basic payments.
 This version of the tutorial has examples for Python3. It uses the
@@ -51,18 +55,23 @@ languages/environments are available as well.
 If you want to look at some simple, running examples, check out these:
 -  The `essay
-   merchant <>`__
+   merchant 
    that sells single chapters of a book.
 -  The `donation
-   page 
+   page 
    that accepts donations for software projects and gives donation
 -  The
-   `survey 
+   `survey 
    that gives users who answer a question a small reward.
+-  The `WooCommerce plugin 
+   which is a comprehensive integration into a Web shop including the refund 
+   process.
 Architecture overview
@@ -97,9 +106,11 @@ with the exchange, and also does not deal with sensitive 
data. In
 particular, the merchant’s signing keys and bank account information are
 encapsulated within the Taler backend.
-Some functionality of the backend (the “public interface“) is also
-exposed to the customer’s browser directly. In the HTTP API, all public
-endpoints are prefixed with ``/public/``.
+Some functionality of the backend (the “public interface“) is exposed to the
+customer’s browser directly. In the HTTP API, all private endpoints (for the
+Backoffice) are prefixed with ``/private/``.  This tutorial focuses on the
+``/private/`` endpoints. The public interface is directly used by the wallet
+and not relevant for the merchant (other than that the API must be exposed).
 .. index:: sandbox, authorization
@@ -108,7 +119,7 @@ Public Sandbox Backend and Authentication
 How the frontend authenticates to the Taler backend depends on the
-configuration. See Taler Merchant Operating Manual.
+configuration. See :doc:`taler-merchant-manual`.
 The public sandbox backend uses an API
 key in the ``Authorization`` header. The value of this header must be
@@ -143,16 +154,20 @@ id ``default`` is assumed.
 The following merchant instances are configured on
--  ``GNUnet`` (The GNUnet project)
+-  ``GNUnet`` (The GNUnet project), reachable at
--  ``FSF`` (The Free Software Foundation)
+-  ``FSF`` (The Free Software Foundation), reachable at
--  ``Tor`` (The Tor Project)
+-  ``Tor`` (The Tor Project), reachable at
--  ``default`` (Kudos Inc.)
+-  ``default`` (Kudos Inc.), reachable at
+.. Note:: These are fictional merchants used for our demonstrators and
+   not affiliated with or officially approved by the respective projects.
+All endpoints for instances offer the same API. Thus, which instance is
+to be used is simply included in the base URL of the merchant backend.
-Note that these are fictional merchants used for our demonstrators and
-not affiliated with or officially approved by the respective projects.
 .. _Merchant-Payment-Processing:
@@ -169,8 +184,12 @@ description of the business transaction for which the 
payment is to be
 made. Before accepting a Taler payment as a merchant you must create
 such an order.
-This is done by posting a JSON object to the backend’s ``/order`` API
-endpoint. At least the following fields must be given:
+This is done by POSTing a JSON object to the backend’s ``/private/orders`` API
+endpoint. At least the following fields must be given inside the ``order``
+.. index:: summary
+.. index:: fulfillment URL
 -  amount: The amount to be paid, as a string in the format
    ``CURRENCY:DECIMAL_VALUE``, for example ``EUR:10`` for 10 Euros or
@@ -187,52 +206,87 @@ endpoint. At least the following fields must be given:
    as the ``session_sig`` for session-bound payments (discussed later).
 Orders can have many more fields, see `The Taler Order
-Format <#The-Taler-Order-Format>`__.
+Format <#The-Taler-Order-Format>`__.  When POSTing an order,
+you can also specify additional details such as an override
+for the refund duration and instructions for inventory
+management. These are rarely needed and not covered in this
+tutorial, please read the :doc:`core/api-merchant` reference
+manual for details.
-After successfully ``POST``\ ing to ``/order``, an ``order_id`` will be
-returned. Together with the merchant ``instance``, the order id uniquely
-identifies the order within a merchant backend.
+A minimal Python snippet for creating an order would look like this:
    >>> import requests
-   >>> order = dict(order=dict(amount="KUDOS:10",
-   ...                         summary="Donation",
-   ...                         
-   >>> order_resp ="";, 
+   >>> body = dict(order=dict(amount="KUDOS:10",
+   ...                        summary="Donation",
+   ...                        
+   ...             create_token=false)
+   >>> response ="";,
+   ...               json=body,
    ...               headers={"Authorization": "ApiKey sandbox"})
    <Response [200]>
+.. index:: claim token
 The backend will fill in some details missing in the order, such as the
 address of the merchant instance. The full details are called the
-*contract terms*. contract terms
+*contract terms*.
+.. index:: contract terms
+.. note::
+   The above request disables the use of claim tokens by setting the
+   ``create_token`` option to ``false``.  If you need claim tokens,
+   you must adjust the code to construct the ``taler://pay/`` URI
+   given below to include the claim token.
+After successfully ``POST``\ ing to ``/private/orders``, an ``order_id`` will 
+returned. Together with the merchant ``instance``, the order id uniquely
+identifies the order within a merchant backend.  Using the order ID, you
+can trivially construct the respective ``taler://pay/`` URI that must
+be provided to the wallet.  Let ```` be the domain name where
+the public endpoints of the instance are reachable. The Taler pay URI is
+then simply ``taler://pay/$ORDER_ID/`` where ``$ORDER_ID``
+must be replaced with the ID of the order that was returned.
+You can put the ``taler://`` URI as the target of a link to open the Taler
+wallet via the ``taler://`` schema, or put it into a QR code.  However, for a
+Web shop, the easiest way is to simply redirect the browser to
+``$ORDER_ID/``.  That page will then trigger the
+Taler wallet. Here the backend generates the right logic to trigger the
+wallet, supporting the various types of Taler wallets in existence.  Instead
+of constructing the above URL by hand, it is best to obtain it by checking for
+the payment status as described in the next section.
 Checking Payment Status and Prompting for Payment
-The status of a payment can be checked with the ``/check-payment``
-endpoint. If the payment is yet to be completed by the customer,
-``/check-payment`` will give the frontend a URL (the
-payment_redirect_url) that will trigger the customer’s wallet to execute
-the payment.
+Given the order ID, the status of a payment can be checked with the
+``/private/orders/$ORDER_ID/`` endpoint. If the payment is yet to be completed
+by the customer, ``/private/orders/$ORDER_ID`` will give the frontend a URL
+(under the name ``payment_redirect_url``) that will trigger the customer’s
+wallet to execute the payment. This is basically the
+``$ORDER_ID/`` URL we discussed above. Note
-Note that the only way to obtain the payment_redirect_url is to check
-the status of the payment, even if you know that the user did not pay
+Note that the best way to obtain the ``payment_redirect_url`` is to check the
+status of the payment, even if you know that the user did not pay yet.  There
+are a few corner cases to consider when constructing this URL, so asking the
+backend to do it is the safest method.
    >>> import requests
-   >>> r = requests.get("";,
-   ...                  params=dict(order_id=order_resp.json()["order_id"]),
+   >>> r = requests.get(""; + 
    ...                  headers={"Authorization": "ApiKey sandbox"})
    >>> print(r.json())
-If the paid field in the response is ``true``, the other fields in the
-response will be different. Once the payment was completed by the user,
-the response will contain the following fields:
--  paid: Set to true.
+If the ``order_status`` field in the response is ``paid``, you will not
+get a ``payment_redirect_url`` and instead information about the
+payment status, including:
 -  contract_terms: The full contract terms of the order.
@@ -241,13 +295,18 @@ the response will contain the following fields:
 -  refunded_amount: Amount that was refunded
--  last_session_id: Last session ID used by the customer’s wallet. See
-   `Session-Bound Payments <#Session_002dBound-Payments>`__.
 Once the frontend has confirmed that the payment was successful, it
 usually needs to trigger the business logic for the merchant to fulfill
 the merchant’s obligations under the contract.
+.. Note::
+   You do not need to keep querying to notice changes
+   to the order's transaction status.  The endpoint
+   support long polling, simply specify a ``timeout_ms``
+   query parameter with how long you want to wait at most
+   for the order status to change to ``paid``.
 .. _Giving-Refunds:
 .. index:: refunds
@@ -264,13 +323,9 @@ order. The default value for this refund deadline is 
specified in the
 configuration of the merchant’s backend.
 The frontend can instruct the merchant backend to authorize a refund by
-``POST``\ ing to the ``/refund`` endpoint.
-The refund request JSON object has the following fields:
--  order_id: Identifies for which order a customer should be refunded.
+``POST``\ ing to the ``/private/orders/$ORDER_ID/refund`` endpoint.
--  instance: Merchant instance to use.
+The refund request JSON object has only two fields:
 -  refund: Amount to be refunded. If a previous refund was authorized
    for the same order, the new amount must be higher, otherwise the
@@ -281,7 +336,7 @@ The refund request JSON object has the following fields:
    only used by the Back Office and is not exposed to the customer.
 If the request is successful (indicated by HTTP status code 200), the
-response includes a ``refund_redirect_url``. The frontend must redirect
+response includes a ``taler_refund_uri``. The frontend must redirect
 the customer’s browser to that URL to allow the refund to be processed
 by the wallet.
@@ -290,14 +345,25 @@ This code snipped illustrates giving a refund:
    >>> import requests
-   >>> refund_req = dict(order_id="2018.",
-   ...                   refund="KUDOS:10",
-   ...                   instance="default",
+   >>> refund_req = dict(refund="KUDOS:10",
    ...                   reason="Customer did not like the product")
-   >>>"";, json=refund_req,
-   ...              headers={"Authorization": "ApiKey sandbox"})
+   >>>"";
+   ...               + order_id + "/refund", json=refund_req,
+   ...               headers={"Authorization": "ApiKey sandbox"})
    <Response [200]>
+.. Note::
+   After granting a refund, the public
+   ``$ORDER_ID/`` endpoint will
+   change its wallet interaction from requesting payment to
+   offering a refund.  Thus, frontends may again redirect
+   browsers to this endpoint.  However, to do so, a
+   ``h_contract`` field must be appended
+   (``?h_contract=$H_CONTRACT``) as the public endpoint requires
+   it to authenticate the client.  The required
+   ``$H_CONTRACT`` value is returned in the refund response
+   under the ``h_contract`` field.
 .. index:: repurchase
 .. _repurchase:
@@ -305,6 +371,8 @@ This code snipped illustrates giving a refund:
 Repurchase detection and fulfillment URLs
+.. TODO:: This section needs to be reviewed for 0.8.
 A possible problem for merchants selling access to digital articles
 is that a customer may have paid for an article on one device, but
 may then want to read it on a different device, possibly one that
@@ -348,6 +416,9 @@ unique.
 Giving Customers Tips
+.. TODO:: This section needs to be updated for 0.8.
 GNU Taler allows Web sites to grant small amounts directly to the
 visitor. The idea is that some sites may want incentivize actions such
 as filling out a survey or trying a new feature. It is important to note
@@ -407,115 +478,15 @@ This code snipped illustrates giving a tip:
 Advanced topics
-.. _Detecting-the-Presence-of-the-Taler-Wallet:
-Detecting the Presence of the Taler Wallet
-Taler offers ways to detect whether a user has the wallet installed in
-their browser. This allows Web sites to adapt accordingly. Note that not
-all platforms can do presence detection reliably. Some platforms might
-have a Taler wallet installed as a separate App instead of using a Web
-extension. In these cases, presence detection will fail. Thus, sites may
-want to allow users to request Taler payments even if a wallet could not
-be detected, especially for visitors using mobiles.
-Presence detection without JavaScript
-Presence detection without JavaScript is based on CSS classes. You can
-hide or show elements selectively depending on whether the wallet is
-detected or not.
-In order to work correctly, a special fallback stylesheet must be
-included that will be used when the wallet is not present. The
-stylesheet can be put into any file, but must be included via a ``link``
-tag with the ``id`` attribute set to ``taler-presence-stylesheet``. If a
-wallet is present, it will “hijack” this stylesheet to change how
-elements with the following classes are rendered:
-The following CSS classes can be used:
-   A CSS rule will set the ``display`` property for this class to
-   ``none`` once the Taler wallet is installed and enabled. If the
-   wallet is not installed, ``display`` will be ``inherit``.
-   A CSS rule will set the ``display`` property for this class to
-   ``inherit`` once the Taler wallet is installed and enabled. If the
-   wallet is not installed, ``display`` will be ``none``.
-The following is a complete example:
-   <!DOCTYPE html>
-   <html data-taler-nojs="true">
-     <head>
-       <title>Tutorial</title>
-       <link rel="stylesheet"
-             type="text/css"
-             href="/web-common/taler-fallback.css"
-             id="taler-presence-stylesheet" />
-     </head>
-     <body>
-       <p class="taler-installed-hide">
-         No wallet found.
-       </p>
-       <p class="taler-installed-show">
-         Wallet found!
-       </p>
-     </body>
-   </html>
-The ``taler-fallback.css`` is part of the Taler’s *web-common*
-repository, available at
- You may
-have to adjust the ``href`` attribute in the HTML code above to point to
-the correct location of the ``taler-fallback.css`` file on your Web
-Detection with JavaScript
-The following functions are defined in the ``taler`` namespace of the
-``taler-wallet-lib`` helper library available at
-``onPresent(callback: () => void)``
-   Adds a callback to be called when support for Taler payments is
-   detected.
-``onAbsent(callback: () => void)``
-   Adds a callback to be called when support for Taler payments is
-   disabled.
-Note that the registered callbacks may be called more than once. This
-may happen if a user disables or enables the wallet in the browser’s
-extension settings while a shop’s frontend page is open.
-.. _Integration-with-the-Back-Office:
-Integration with the Back Office
-Taler ships a Back Office application as a stand-alone Web application.
-The Back Office has its own documentation at
-Developers wishing to tightly integrate back office support for
-Taler-based payments into an existing back office application should
-focus on the wire transfer tracking and transaction history sections of
-the Taler Backend API specification at
+.. TODO:: This section needs to be updated for 0.8.
 .. _Session_002dBound-Payments:
 Session-Bound Payments
+.. index:: session
 Sometimes checking if an order has been paid for is not enough. For
 example, when selling access to online media, the publisher may want to
 be paid for exactly the same product by each customer. Taler supports
@@ -531,7 +502,9 @@ browser an ephemeral ``session_id``, usually via a session 
cookie. When
 executing or re-playing a payment, the wallet will receive an additional
 signature (``session_sig``). This signature certifies that the wallet
 showed a payment receipt for the respective order in the current
-session. cookie
+.. index:: cookie
 Session-bound payments are triggered by passing the ``session_id``
 parameter to the ``/check-payment`` endpoint. The wallet will then
@@ -549,7 +522,8 @@ in the response to ``/check-payment``.
 Product Identification
-resource url
+.. index:: resource url
 In some situations the user may have paid for some digital good, but the
 frontend does not know the exact order ID, and thus cannot instruct the
 wallet to reveil the existing payment receipt. This is common for simple
@@ -564,6 +538,7 @@ the product. The wallet will then check whether it has paid 
for a
 contract with the same ``resource_url`` before, and if so replay the
 previous payment.
 .. _The-Taler-Order-Format:
 The Taler Order Format
@@ -575,29 +550,28 @@ describes each of the fields in depth.
 Financial amounts are always specified as a string in the format
-   amount
    Specifies the total amount to be paid to the merchant by the
+   .. index:: amount
-   fees
-   maximum deposit fee
    This is the maximum total amount of deposit fees that the merchant is
    willing to pay. If the deposit fees for the coins exceed this amount,
    the customer has to include it in the payment total. The fee is
    specified using the same triplet used for amount.
+   .. index:: fees
+   .. index:: maximum deposit fee
-   fees
-   maximum wire fee
    Maximum wire fee accepted by the merchant (customer share to be
    divided by the ’wire_fee_amortization’ factor, and further reduced if
    deposit fees are below ’max_fee’). Default if missing is zero.
+   .. index:: fees
+   .. index:: maximum wire fee
-   fees
-   maximum fee amortization
    Over how many customer transactions does the merchant expect to
    amortize wire fees on average? If the exchange’s wire fee is above
    ’max_wire_fee’, the difference is divided by this number to compute
@@ -606,35 +580,36 @@ wire_fee_amortization
    ’max_fee’ and the sum of the actual deposit fees. Optional, default
    value if missing is 1. 0 and negative values are invalid and also
    interpreted as 1.
+   .. index:: fees
+   .. index:: maximum fee amortization
-   pay_url
    Which URL accepts payments. This is the URL where the wallet will
    POST coins.
+   .. index:: pay_url
-   fulfillment URL
    Which URL should the wallet go to for obtaining the fulfillment, for
    example the HTML or PDF of an article that was bought, or an order
    tracking system for shipments, or a simple human-readable Web page
    indicating the status of the contract.
+   .. index:: fulfillment URL
-   order ID
    Alphanumeric identifier, freely definable by the merchant. Used by
    the merchant to uniquely identify the transaction.
+   .. index:: order ID
-   summary
    Short, human-readable summary of the contract. To be used when
    displaying the contract in just one line, for example in the
    transaction history of the customer.
+   .. index:: summary
    Time at which the offer was generated.
-   payment deadline
    Timestamp of the time by which the merchant wants the exchange to
    definitively wire the money due from this contract. Once this
    deadline expires, the exchange will aggregate all deposits where the
@@ -642,20 +617,21 @@ pay_deadline
    payment for them. Amounts will be rounded down to the wire transfer
    unit; if the total amount is still below the wire transfer unit, it
    will not be disbursed.
+   .. index:: payment deadline
-   refund deadline
    Timestamp until which the merchant willing (and able) to give refunds
    for the contract using Taler. Note that the Taler exchange will hold
    the payment in escrow at least until this deadline. Until this time,
    the merchant will be able to sign a message to trigger a refund to
    the customer. After this time, it will no longer be possible to
    refund the customer. Must be smaller than the pay_deadline.
+   .. index:: refund deadline
-   product description
    Array of products that are being sold to the customer. Each entry
    contains a tuple with the following values:
+   .. index:: product description
       Description of the product.
@@ -714,7 +690,6 @@ merchant
       jurisdiction under which this contract is to be arbitrated.
-   location
    Associative map of locations used in the contract. Labels for
    locations in this map can be freely chosen and used whenever a
    location is required in other parts of the contract. This way, if the
@@ -722,6 +697,7 @@ locations
    the customer or the merchant), it only needs to be listed (and
    transmitted) once, and can otherwise be referred to via the label. A
    non-exhaustive list of location attributes is the following:
+   .. index:: location
       receiver name for delivery, either business or person name.
@@ -753,7 +729,9 @@ locations
       Street number (number of the house) for delivery, as found on a
       postal package.
-   Note that locations are not required to specify all of these fields,
+.. Note::
+   Locations are not required to specify all of these fields,
    and they is also allowed to have additional fields. Contract
    renderers must render at least the fields listed above, and should
    render fields that they do not understand as a key-value list.
diff --git a/taler-merchant-manual.rst b/taler-merchant-manual.rst
index 60fe441..bd36b43 100644
--- a/taler-merchant-manual.rst
+++ b/taler-merchant-manual.rst
@@ -1,3 +1,5 @@
+.. _ffoobar:
 GNU Taler Merchant Backend Operator Manual
@@ -1516,7 +1518,7 @@ A relatively minimal configuration could look like this:
 Note that the public key must match the exchange's
 private key and that the Postgres database must
 exist before launching the benchmark.  You also
-will need to ensure that the Exchange's 
+will need to ensure that the Exchange's
 details are setup, usually by running

To stop receiving notification emails like this one, please contact

reply via email to

[Prev in Thread] Current Thread [Next in Thread]