summaryrefslogtreecommitdiff
path: root/orphaned
diff options
context:
space:
mode:
Diffstat (limited to 'orphaned')
-rw-r--r--orphaned/README2
-rw-r--r--orphaned/python-guidelines.rst56
-rw-r--r--orphaned/qa-0.9.4.rst228
-rw-r--r--orphaned/taler-mcig.rst563
-rw-r--r--orphaned/taler-nfc-guide.rst285
5 files changed, 1134 insertions, 0 deletions
diff --git a/orphaned/README b/orphaned/README
new file mode 100644
index 00000000..4035e4b4
--- /dev/null
+++ b/orphaned/README
@@ -0,0 +1,2 @@
+This document contains documentation that we currently don't link anywhere,
+but that we might still want to salvage sometime.
diff --git a/orphaned/python-guidelines.rst b/orphaned/python-guidelines.rst
new file mode 100644
index 00000000..8a644ced
--- /dev/null
+++ b/orphaned/python-guidelines.rst
@@ -0,0 +1,56 @@
+Guidelines for Python Packages
+==============================
+
+This document describes conventions used for Python repos in the Taler project.
+
+
+Packaging
+---------
+
+* We use `poetry <https://github.com/python-poetry/poetry>`__ for managing dependencies and dev-dependencies.
+* The ``poetry.lock`` file must be committed to repo.
+* Entry points **must not** be defined as shell scripts. Instead, use poetry's script facility to define entry points. This makes the package work on different platforms properly.
+
+
+GNU Compatibility Layer
+-----------------------
+
+In addition to the Python-native tooling, we provide a GNU-style interface for the build system.
+The commands supported by every Python repo should be:
+
+* ``./bootstrap``: Only necessary when the repo is checked out via git.
+ Initializes the build system and checks out git submodules if applicable.
+* ``./configure``: Should check for build-time dependencies, **including** Python tooling.
+* ``make``: Invoking make without a target should create the Python wheel for the project.
+* ``make install``: Installation should **only** install the Python package
+ based on the wheel via ``pip``. Note that we can't do dependency tracking
+ properly, so the ``install`` target will always re-build the wheel and
+ install it.
+* ``make pretty``: Should invoke the pretty-printer (``black`` for Python projects).
+* ``make dist``: This should create the source tarball.
+* ``make clean``: Should delete generated files.
+
+The `build-common.git <https://git.taler.net/build-common.git/>`__ repository contains helpers
+to make the GNU compatibility easier. Here are some hints for using it:
+
+* The ``build-common.git`` repo should added as a submodule in the path ``build-system/taler-build-scripts``
+ of the repository.
+* The `bootstrap template <https://git.taler.net/build-common.git/tree/bootstrap.template>`__ should
+ be copied as ``./bootstrap`` to the root of the repository.
+* The configure script is automatically created by ``./bootstrap``.
+* Dependencies for the configure file are defined in ``build-system/configure.py``.
+ There is no documentation yet, but adjusting the `example file <https://git.taler.net/build-common.git/tree/testconfigure.py>`__ is a good starting point.
+* The source distribution (``make dist``) should either be created via ``poetry build -f sdist``
+ or using the `git-archive-all <https://git.taler.net/build-common.git/tree/archive-with-submodules/git_archive_all.py>`__.
+
+Formatting
+----------
+
+* We follow `pep8 <https://www.python.org/dev/peps/pep-0008/>`__.
+* Code should be auto-formatted with `black <https://github.com/psf/black>`__.
+
+
+Distro Packaging
+----------------
+
+For Debian, we should try to use `wheel2deb <https://github.com/upciti/wheel2deb>`__.
diff --git a/orphaned/qa-0.9.4.rst b/orphaned/qa-0.9.4.rst
new file mode 100644
index 00000000..77e51081
--- /dev/null
+++ b/orphaned/qa-0.9.4.rst
@@ -0,0 +1,228 @@
+Taler 0.9.4 QA Plan
+-------------------
+
+Wallet Platforms
+^^^^^^^^^^^^^^^^
+
+Platforms listed here are the officially supported platforms for this release.
+
+* Overview / Installation Page
+
+ * https://taler.net/en/wallet.html
+
+* Android
+
+ * Google Play: https://play.google.com/store/apps/details?id=net.taler.wallet
+ * F-Droid: https://f-droid.org/en/packages/net.taler.wallet.fdroid/
+ * APK Download: TBD
+
+* Browser
+
+ * Chrome: https://chromewebstore.google.com/detail/gnu-taler-wallet/millncjiddlpgdmkklmhfadpacifaonc
+ * Firefox: https://addons.mozilla.org/en-US/firefox/addon/taler-wallet/
+
+* iOS
+
+
+Running Deployments
+^^^^^^^^^^^^^^^^^^^
+
+These deployments are maintained by us and should work for the release:
+
+* Sandcastle-based:
+
+ * demo.taler.net
+
+ * test.taler.net
+
+* Regio-based:
+
+ * regio-taler.fdold.eu
+
+
+Wallet Flows
+^^^^^^^^^^^^
+
+* Bank-integrated withdrawal
+
+ * webext: "Continue with Mobile Wallet" flow
+
+* Manual withdrawal
+
+ * ``taler://withdraw-exchange`` flow
+
+ * Currency conversion withdrawal
+
+* Peer push payments ("Send Money")
+
+* Peer pull payments ("Receive Money")
+
+* Deposit into bank account
+
+ * Check that deposit arrived
+
+* Payment at merchant
+
+ * on blog merchant
+ * on survey
+ * directly initiated via merchant SPA
+ * webext: "Pay with Mobile Wallet" flow
+
+* Pay templates
+
+ * Payment TOTP codes
+
+* Exchange management
+
+ * Reloading exchange keys
+ * Deleting an exchange
+
+
+libeufin-bank Flows
+^^^^^^^^^^^^^^^^^^^
+
+* Admin functionality
+
+ * Login
+
+ * Credential change
+
+ * Conversion settings
+
+ * Bank account creation
+
+ * Test transfers
+
+* Normal account functionality
+
+ * Transfers
+
+ * Transfer to the exchange should bounce
+
+ * Withdrawals
+
+ * (conversion-only): Test cash-in
+
+ * (conversion-only): Test cash-out
+
+ * Lower cash-out limit enforced
+
+ * 2FA for withdrawals, cash-out
+
+
+Merchant Backend SPA Flows
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Instance creation
+
+* Simple bank account setup
+
+* Order creation
+
+ * Pay order (with short wire transfer deadline)
+
+ * Check that money from order arrive at the bank with the right subject
+
+* Extended bank account setup
+
+ * Add Taler Bank Revenue API
+
+ * Check bank transfer list (for wire transfer of previously paid+wired order)
+
+ * Check order payment status goes to "final" automatically
+
+* TOTP Device Management
+
+ * Add device
+
+ * Edit device (set new secret, export new secret as QR code)
+
+ * Delete device
+
+* Templates
+
+ * Add template
+
+ * Edit template
+
+ * Add TOTP device to template
+
+ * Edit TOTP device associated with template
+
+ * Pay template
+
+ * Check TOTP code matches
+
+ * Remove TOTP device from template
+
+ * Delete template
+
+
+
+Regio Deployment
+^^^^^^^^^^^^^^^^
+
+* Deployment Automation (deployment.git/regional-currency)
+
+ * Test with Debian bookworm
+
+ * Test with Ubuntu mantic
+
+ * Check logs for errors
+
+ * Test with telesign (SMS)
+
+ * Set up EBICS integration
+
+ * Check that ToS is configured
+
+* Deployment Functionality
+
+ * All flows of the wallet should work (see ``Wallet Flows`` above)
+
+ * All flows of libeufin-bank should work (see ``libeufin-bank Flows`` above)
+
+ * Merchant backend should work (see ``Merchant Backend SPA Flows`` above)
+
+ * Check logs
+
+
+Android Merchant PoS
+^^^^^^^^^^^^^^^^^^^^
+
+* Test against demo.taler.net
+
+
+Android Cashier App
+^^^^^^^^^^^^^^^^^^^
+
+* Test against demo.taler.net
+
+
+CI
+^^
+
+* https://buildbot.taler.net/#/waterfall
+* CI should pass
+
+
+Debian Repository
+^^^^^^^^^^^^^^^^^
+
+* Debian
+
+ * repo at https://deb.taler.net/apt/debian/
+ * supported codename(s): bookworm
+
+
+* Ubuntu:
+
+ * repo at https://deb.taler.net/apt/ubuntu/
+ * supported codename(s): mantic
+
+
+GNU Release
+^^^^^^^^^^^
+
+* Release announcement
+* FTP upload
diff --git a/orphaned/taler-mcig.rst b/orphaned/taler-mcig.rst
new file mode 100644
index 00000000..1950f4af
--- /dev/null
+++ b/orphaned/taler-mcig.rst
@@ -0,0 +1,563 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2021 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 Thien-Thi Nguyen
+
+
+Merchant/Customer Interaction Guide
+###################################
+
+The audience for the Mechant/Customer Interaction Guide is the merchant
+who wishes to set up a "web shop" that works with the Taler payment system.
+
+
+Introduction
+============
+
+.. include:: frags/taler-payment-cycle.rst
+
+This guide focuses on step 4, the interaction between the customer and the
+merchant. In particular, we first review two basic interaction flows
+(with and without shopping cart), then describe Taler features involved in the
+interaction, the decisions you (the merchant) must make, and
+how to configure the Taler merchant backend to best support those decisions.
+Lastly, we present protocol *traces* for various fictitious interaction flows.
+
+
+Two Basic Flows
+===============
+
+.. index:: shopping cart experience
+.. index:: individual product selection / purchase experience
+.. index:: inventory management
+.. index:: repurchase detection / prevention
+
+There are two basic payment flows, the first involving a shopping cart,
+and the second, without (individual product selection / purchase).
+We distinguish these because for some purchases, a shopping cart is overkill.
+In either case, Taler can integrate
+with your *inventory management* system.
+Additionally, Taler offers *repurchase detection / prevention*,
+most suitable for digital goods.
+
+In the shopping cart experience, you first offer a product on the website.
+The customer adds the product to their shopping cart, at which point you may
+optionally *lock* the product in the inventory system for a certain period of
+time.
+The accumulated set of products in the shopping cart is the *order*.
+This process repeats until the customer is ready to move to the
+*checkout* phase.
+
+At checkout, you may optionally support different payment methods (and make
+this choice available to the customer) for the order.
+This guide assumes you and the customer agree to use the Taler payment system.
+
+At this point, you generate a *contract* and present it to the customer for
+authorization.
+The contract includes:
+
+- the total amount due;
+- a short summary;
+- a *fulfillment URI*;
+- the *duration* of the offer (how long the customer has to authorize before timeout);
+- (optional) an itemized product list, with:
+
+ - (optional) some kind of identification for the selected product(s);
+
+- (optional) applicable taxes and fee limits;
+- (optional) an order ID (if omitted, the backend will auto-generate one);
+- (optional) information which details are *forgettable*;
+- (optional) a *claim token* that the customer can use later;
+- (optional) information on the *refund deadline*;
+- (optional) information on the *auto-refund period* (how long does the wallet check for refunds without user prompting for it).
+
+If the customer does nothing (timeout / the contract expires),
+the merchant backend automatically *unlocks* the product(s),
+allowing other consumers to add more items of the limited stock
+to their orders.
+
+On the other hand, if the customer authorizes payment,
+the customer's wallet transfers payment coins to you,
+previously locked products are removed from inventory,
+and (if possible) the wallet redirects the customer
+to the *fulfillment URI*.
+
+The individual product selection / purchase experience is like the shopping
+cart experience with the following exceptions:
+- there is no shopping cart -- the order is solely the selected product;
+- Taler payment method is assumed;
+- customer selection moves directly to checkout;
+- *repurchase detection / prevention* can be useful (for digital products).
+
+
+Taler Details
+=============
+
+This section describes aspects of Taler involved
+in the basic payment flows in more detail.
+Each aspect also includes one or more backend API calls that
+are demonstrated in the next section.
+
+**product locking**
+ Taler can integrate with your inventory system to set aside
+ a certain quantity of a product for some duration of time.
+ This is called *product locking*.
+ This is useful for physical goods, or for goods that have a limited supply,
+ such as airline tickets.
+ Even for digital goods, product locking may be useful to effect exclusivity.
+
+ To lock a product, use:
+ :http:post:`[/instances/$INSTANCE]/private/products/$PRODUCT_ID/lock`,
+ specifying a ``duration`` and a ``quantity``.
+
+ If the customer removes a product from the shopping cart, you can *unlock*
+ the product by using the same API call, specifying a ``quantity`` of 0 (zero).
+ (Products are also unlocked automatically on timeout / contract expiration.)
+
+ Before you can lock products, you need to manage the inventory, creating
+ an entry for the product (assigning a $PRODUCT_ID) and configure the
+ available stock. This can be done using the
+ Taler merchant backoffice Web interface.
+
+ .. note::
+
+ Once we have documentation for that web interface, we should link to it here.
+
+**taxes**
+ The default taxes for each product is part of the product ``price``
+ maintained by the backend.
+ Taxes can be set when the product is added to the inventory,
+ prior to any customer purchase experience
+ (see :http:post:`[/instances/$INSTANCE]/private/products`,
+ :http:get:`[/instances/$INSTANCE]/private/products`,
+ and :http:get:`[/instances/$INSTANCE]/private/products/$PRODUCT_ID`)
+ or specified explicitly by the frontend when adding
+ products to an order that are not managed by the backend inventory
+ (see :http:post:`[/instances/$INSTANCE]/private/orders`).
+
+**fees**
+ The Taler protocol charges a *deposit fee* (see step 5, above),
+ which you may choose to pay or to pass on to the customer.
+ This can be configured to a maximum amount, per order.
+
+ You can set ``default_max_deposit_fee`` in :http:post:`/management/instances`,
+ or override the default by setting ``max_fee`` when creating an order.
+
+ There is also the *wire fee* (see step 6, above),
+ which you may choose to pay or to pass on to the customer.
+
+ You can set ``default_max_wire_fee`` in :http:post:`/management/instances`,
+ and ``max_wire_fee`` in the contract.
+ If unspecified, the default value is zero (meaning you bear the entire fee).
+
+ You can *amortize* the wire fee across a number of customers
+ by setting ``default_wire_fee_amortization`` in :http:post:`/management/instances`,
+ and ``wire_fee_amortization`` in the contract.
+ This is the number of customer transactions over which you expect to
+ amortize wire fees on average.
+ If unspecified, the default value is one.
+
+ .. Note:: :http:post:`/management/instances` must be done at
+ instance-setup time (prior to any purchase).
+
+**forgettable customer details**
+ Although Taler allows the customer to remain anonymous, you may need to
+ collect customer details (e.g. for shipping).
+ Taler has support for forgetting such details, to comply with GDPR
+ (for example).
+ This can occur even in the face of refunds (see below).
+
+ To forget a set of details, first the details that are to be forgotten
+ must be marked by including the names of the respective fields
+ in one or more special ``_forgettable`` field(s) in the contract.
+
+ Then, you can use:
+ :http:patch:`[/instances/$INSTANCE]/private/orders/$ORDER_ID/forget`
+ to forget those details.
+
+**claim token**
+ The claim token is a sort of handle on the order and its payment.
+ It is useful when the order ID is easily guessable
+ (e.g. incrementing serial number),
+ to prevent one customer hijacking the order of another.
+ On the other hand, even if the order ID is not easily guessable,
+ if you don't care about order theft (e.g. infinite supply, digital goods)
+ and you wish to reduce the required processing (e.g. smaller QR code),
+ you can safely disable the claim token.
+
+ By default, Taler creates a claim token for each order.
+ To disable this, you can specify ``create_token`` to be ``false``
+ in :http:post:`[/instances/$INSTANCE]/private/orders`.
+
+**refund deadline**
+ The refund deadline specifies the time after which you will prohibit
+ refunds.
+ Refunds may be full or partial.
+ Refunds do not require customer details.
+ You can configure the deadline to expire immediately to effect
+ an "all sales are final" policy.
+
+ To set the deadline, specify ``refund_delay``
+ in :http:post:`[/instances/$INSTANCE]/private/orders`.
+ To disable refunds altogether, omit this field.
+
+**auto-refund period**
+ The Taler protocol can automatically offer refunds to the customer's
+ wallet without their explicit prompting during the auto-refund period.
+
+ This is useful in the case where the purchase cannot be fulfilled
+ (e.g. jammed vending machine), but there is no way to notify the
+ customer about a refund.
+
+ If specified, after contract authorization, the customer's wallet will
+ repeatedly check for either fulfillment or refund, up to the end of
+ the auto-refund period.
+ (If neither occur within that period, the customer should complain
+ to you for breach of contract.)
+
+ To set the auto-refund period, specify ``auto_refund``
+ in :http:post:`[/instances/$INSTANCE]/private/orders`.
+
+**repurchase detection / prevention**
+ Taler can detect a repurchase attempt and prevent it from going through.
+ This feature allows customers to purchase a digital good only once,
+ but to later access the same digital good repeatedly (e.g. reload
+ in browser, after network trouble, etc.) without having to pay again.
+
+ This feature is automatic in the protocol;
+ you do not need to do anything to enable it.
+
+ .. note::
+ For repurchase detection / prevention to work reliably,
+ you must use the same fulfillment URI for the same product
+ and likewise different fulfillment URIs for different products.
+
+**fulfillment URI**
+ This may be the actual product (digital goods),
+ or a tracking URL (physical goods).
+ If you issue a claim token with the contract, the customer can
+ access the fulfillment URI from a different device than the
+ one where the wallet is installed.
+
+ The fulfillment URI is normally included in the contract.
+ You specify it in :http:post:`[/instances/$INSTANCE]/private/orders`.
+
+ If the fulfillment URI contains the literal string ``${ORDER_ID}``
+ (including curly braces), that will be replaced by the order ID when
+ POSTing to the merchant. (FIXME: What does "POSTing to the merchant" mean?)
+ This is useful when the backend auto-generates the order ID.
+
+
+Sample Interaction Traces
+=========================
+
+In the following descriptions, ``C`` stands for *customer*, ``W`` stands for
+*customer's wallet*, ``M`` stands for *merchant* (you), and ``E`` stands for
+*exchange*.
+Unless otherwise noted, all API calls are directed toward the Taler backend.
+
+Also, all the traces share the initial pre-sales configuration step.
+
+
+Pre-Sales Configuration
+-----------------------
+
+In the pre-sales configuration step, you set up the *default instance*,
+and add products to the inventory.
+
+NOTE: not sure we want to ultimately document this HERE. Most merchants
+should do _this_ part via the Merchant Web interface that Sebastian is
+building right now, and for that we want a separate guide that explains
+the API (as you do here), and the Web interface. In this document,
+we should focus on how the merchant integrates the (Web)front-end with the
+backend, not how the backend itself is configured.
+(This also applies to the other instance setup parts you described
+above => refer to other guide, but of course specify how we can
+override defaults from instance setup per-order.)
+
+
+M: :http:post:`/management/instances`
+
+.. code-block:: javascript
+
+ // InstanceConfigurationMessage
+ {
+ "accounts": [{"payto_uri":"payto://iban/CH9300762011623852957"}],
+ "id": "default",
+ "name": "Pretty Pianos",
+ "auth":
+ // InstanceAuthConfigurationMessage
+ {
+ "method": "external",
+ "token": "secret-token:eighty-eight-keys"
+ },
+ "default_max_wire_fee": "KUDOS:5.0",
+ "default_wire_fee_amortization": 1,
+ "default_max_deposit_fee": "KUDOS:10.0",
+ "default_wire_transfer_delay": "2 days",
+ "default_pay_delay": "5 hours"
+ }
+ // (backend returns 204 No content)
+
+The fictitious store, Pretty Pianos, has only two products:
+- pianos (physical good);
+- *Beethoven Sonatas* (sheet music PDF files, digital good).
+
+M: POST ``/instances/default/private/products``
+
+.. code-block:: javascript
+
+ // ProductAddDetail
+ {
+ "product_id": "p001",
+ "description": "piano",
+ "unit": "unit",
+ "image": "data:image/png;base64,AAA=",
+ "price": "KUDOS:20000.0",
+ "taxes": [],
+ "total_stock": 3,
+ "next_restock": "2021-04-22",
+ "_forgettable": ["image"]
+ }
+ // (backend returns 204 No content)
+
+Note that the ``image`` field is mentioned by name in the ``_forgettable``
+field's list value.
+This means the ``image`` value is *marked as forgettable*.
+This will come into play later (see below).
+
+M: POST ``/instances/default/private/products``
+
+.. code-block:: javascript
+
+ // ProductAddDetail
+ {
+ "product_id": "f001",
+ "description": "Beethoven Sonatas",
+ "unit": "file",
+ "price": "KUDOS:9.87",
+ "taxes": [],
+ "total_stock": -1
+ }
+ // (backend returns 204 No content)
+
+Note that there is no ``next_restock`` field in this ``ProductAddDetail``
+object.
+This is because the ``total_stock`` field has value ``-1`` (meaning "infinite")
+since the product is a PDF file.
+
+
+Scenario 1: Simple File Purchase
+--------------------------------
+
+The first scenario is a simple file purchase, without shopping cart,
+similar to the `GNU Essay demo <https://shop.demo.taler.net/en/>`_ experience.
+
+.. We hardcode "en/" for now because support for other
+ languages is not yet available (at time of writing).
+ (FIXME: Drop "en/" when other languages are supported.)
+
+Because there are infinite supplies of product ``f001``,
+there is really no need for inventory management.
+However, you choose to anyway generate a separate order ID
+in the backend for accounting purposes.
+Also, since the product is an easily reproduced digital good,
+you decline to offer the customer the ability to select a "quantity"
+other than 1 (one), and decide that "all sales are final"
+(no refund possible).
+On the other hand, you wish to enable repurchase detection /
+prevention feature, so that once customers pay for the PDF file,
+they need never pay again for it.
+
+When the customer clicks on the product's "buy" button,
+you first POST to ``/private/orders`` to create an order:
+
+M: POST ``/instances/default/private/orders``
+
+.. code-block:: javascript
+
+ // PostOrderRequest
+ {
+ "order":
+ // Order (MinimalOrderDetail)
+ {
+ "amount": "KUDOS:9.87",
+ "summary": "Beethoven Sonatas",
+ "fulfillment_URI": "https://example.com/f001?${ORDER_ID}"
+ },
+ "create_token": true
+ }
+
+Notes:
+
+- There is no ``refund_delay`` field (no refunds possible).
+- We show the ``create_token`` field with value ``true`` even though that is the default (for illustrative purposes).
+- The ``order`` value is actually a ``MinimalOrderDetail`` object.
+- The ``fulfillment_URI`` value includes the product ID and the literal string ``${ORDER_ID}``, to be replaced by the backend-generated order ID.
+
+The backend returns ``200 OK`` with the body:
+
+.. code-block:: javascript
+
+ // PostOrderResponse
+ {
+ "order_id": "G93420934823",
+ "token": "TEUFHEFBQALK"
+ }
+
+Notes:
+- The backend-generated order ID is ``G93420934823``.
+- The claim token is ``TEUFHEFBQALK``.
+
+(FIXME: Replace w/ more realistic examples?)
+
+Now that there is an order in the system, the wallet *claims* the order.
+
+W: POST ``/orders/G93420934823/claim``
+
+.. code-block:: javascript
+
+ // ClaimRequest
+ {
+ "nonce": "lksjdflaksjfdlaksjf",
+ "token": "TEUFHEFBQALK"
+ }
+
+Notes:
+
+- The ``nonce`` value is a randomly-generated string.
+- The POST endpoint includes the order ID ``G93420934823``.
+- The ``token`` value is the claim token ``TEUFHEFBQALK`` received in the ``PostOrderResponse``.
+
+The backend returns ``200 OK`` with body:
+
+.. code-block:: javascript
+
+ // ContractTerms
+ {
+ "summary": "one copy of Beethoven Sonatas",
+ "order_id": "G93420934823",
+ "amount": "KUDOS:9.87000000",
+ "fulfillment_url": "https://example.com/f001?G93420934823",
+ "max_fee": "KUDOS:0.01500000",
+ "max_wire_fee": "KUDOS:0.01500000",
+ "wire_fee_amortization": 1,
+ "products": [
+ // Product
+ {
+ "product_id": "f001",
+ "description": "Beethoven Sonatas"
+ }
+ ],
+ "timestamp": { "t_ms": 1616537665000 },
+ "refund_deadline": { "t_ms": 1616537665000 },
+ "pay_deadline": { "t_ms": 1616537725000 },
+ "wire_transfer_deadline": { "t_ms": 1616537785000 },
+ "merchant_pub": FIXME,
+ "merchant_base_url": "https://example.com/",
+ "merchant":
+ // Merchant
+ {
+ },
+ "h_wire": FIXME,
+ "wire_method": FIXME,
+ "auditors": [
+ // Auditor
+ ],
+ "exchanges": [
+ // Exchange
+ ],
+ "nonce": "lksjdflaksjfdlaksjf"
+ }
+
+Notes:
+
+- The backend determined both fees to be 0.015 KUDOS.
+ Because the amortization is 1 (one), both fees (processing and wire
+ transfer) are included in full.
+ Thus, the total due by the customer is 9.87 + 0.015 + 0.015 = 9.900 KUDOS.
+- The ``order_id`` value is the one given in the ``PostOrderResponse``.
+- The ``timestamp`` value represents 2021-03-23 22:14:25 UTC
+ in milliseconds after the `epoch <https://en.wikipedia.org/wiki/Unix_epoch>`__.
+- The ``refund_deadline`` value is the same as the ``timestamp`` value
+ (no refunds possible).
+- The ``pay_deadline`` value is one minute after the ``timestamp`` value.
+- The ``wire_transfer_deadline`` value is two minutes after
+ the ``timestamp`` value.
+- The ``products`` value is a list of one element (one ``Product`` object),
+ which omits the ``price`` field since that is included in the
+ ``ContractTerms.amount`` value. Also, its ``quantity`` defaults to 1 (one).
+- The ``nonce`` value is the same one specified by the wallet.
+
+At this point, the wallet displays the contract terms (or a subset of them)
+to the customer, who now has the option to accept the contract or reject it
+(either explicitly by pressing a "cancel" button, or implicitly by waiting
+for the offer to time out).
+
+The customer accepts the contract:
+
+W: POST ``/orders/G93420934823/pay``
+
+.. code-block:: javascript
+
+ // PayRequest
+ {
+ "coins": [
+ // CoinPaySig
+ {
+ "coin_sig": ...,
+ "coin_pub": ...,
+ "ub_sig": ...,
+ "h_denom": ...,
+ "contribution": "KUDOS:8.0",
+ "exchange_url": ...
+ },
+ {
+ "coin_sig": ...,
+ "coin_pub": ...,
+ "ub_sig": ...,
+ "h_denom": ...,
+ "contribution": "KUDOS:2.0",
+ "exchange_url": ...
+ }
+ ]
+ }
+
+Notes:
+
+- There is no session ID in the ``PayRequest`` object.
+- The total of the contribution is 8.0 + 2.0 = 10.0 KUDOS,
+ which is enough to cover the purchase price (9.900 KUDOS
+ from 9.87 + 0.015 + 0.015).
+
+The backend returns ``200 OK`` with body:
+
+.. code-block:: javascript
+
+ // PaymentResponse
+ {
+ "sig": "..." // EddsaSignature
+ }
+
+FIXME: At this point, does the wallet need to query (status)?
+Also, does the frontend need to do anything else?
+
+The wallet then redirects to the fulfillment URI, which displays
+(or makes available for download) the PDF file "Beethoven Sonatas".
+
+
+
+
+TODO/FIXME: Add more scenarios (including JSON).
diff --git a/orphaned/taler-nfc-guide.rst b/orphaned/taler-nfc-guide.rst
new file mode 100644
index 00000000..d025d347
--- /dev/null
+++ b/orphaned/taler-nfc-guide.rst
@@ -0,0 +1,285 @@
+GNU Taler NFC Guide
+###################
+
+This guide explains how NFC (near-field communication) is
+used in the GNU Taler payment system.
+
+Introduction
+============
+
+NFC is currently used for two different purposes:
+
+1. Operations in the wallet (payment, withdrawal, ...) can be triggered by a
+ merchant PoS (Point-of-Sale) terminal or Taler-capable ATM.
+2. When either the wallet or the merchant do not have Internet connectivity,
+ the protocol messages to the exchange or merchant backend service can be
+ tunneled via NFC through the party that has Internet connectivity.
+
+
+Background: Payment Processing with GNU Taler
+=============================================
+
+The following steps show a simple payment process with GNU Taler. Examples are
+written in `Bash <https://www.gnu.org/software/bash/>`_ syntax,
+using `curl <https://curl.haxx.se/docs/manpage.html>`_ to make HTTP(S) requests.
+They make use of the :http:post:`[/instances/$INSTANCE]/private/orders`
+and :http:get:`[/instances/$INSTANCE]/private/orders` endpoints.
+
+1. The merchant creates an *order*, which contains the details of the payment
+ and the product/service that the customer will receive.
+ An order is identified by an alphanumeric *order ID*.
+
+ The *fulfillment URL* is an URL that the wallet will redirect the customer
+ to once the payment is complete. For digital products, this is typically an
+ ``https(s)://`` URL that renders the purchased content. For physical
+ products and in-store purchases, a ``taler://fulfillment-success/<message>``
+ URL should be specified instead. The wallet will display the URL-encoded
+ UTF-8 text ``<message>`` when the payment has succeeded.
+
+ .. hint::
+
+ When an ``http(s)://`` URL is used as the fulfillment URL in an in-store / NFC payment,
+ the user might not be able to view the page, as request tunneling only works for requests
+ made by the wallet to the merchant backend / exchange.
+
+ In these situations, wallets should display to the user that a page to view the purchase
+ can be opened, and give a warning if it is detected that the devices does not have Internet
+ connectivity.
+
+ The following POST ``/private/orders`` request to the merchant backend creates a
+ simple order:
+
+ .. code-block:: console
+
+ $ backend_base_url=https://backend.demo.taler.net/
+ $ auth_header='Authorization: ApiKey sandbox'
+ $ order_req=$(cat <<EOF
+ {
+ "order": {
+ "summary": "one ice cream",
+ "amount": "KUDOS:1.5",
+ "fulfillment_url":
+ "taler://fulfillment-success/Enjoy+your+ice+cream!"
+ }
+ }
+ EOF
+ )
+ $ curl -XPOST -H"$auth_header" -d "$order_req" "$backend_base_url"/private/orders
+ {
+ "order_id": "2019.255-02YDHMXCBQP6J"
+ }
+
+2. The merchant checks the payment status of the order using
+ GET ``/private/orders/$ORDER_ID``:
+
+ .. code-block:: console
+
+ $ backend_base_url=https://backend.demo.taler.net/
+ $ auth_header='Authorization: ApiKey sandbox'
+ $ curl -XGET -H"$auth_header" \
+ "$backend_base_url/private/orders/2019.255-02YDHMXCBQP6J"
+ # Response:
+ {
+ "taler_pay_uri": "taler://pay/backend.demo.taler.net/-/-/2019.255-02YDHMXCBQP6J",
+ "paid": false,
+ # ... (some fields omitted)
+ }
+
+ As expected, the order is not paid. To actually proceed with the payment, the value of ``taler_pay_uri``
+ must be processed by the customer's wallet. There are multiple ways for the wallet to obtain the ``taler://pay/`` URI
+
+ * in a QR code
+ * in the ``Taler:`` HTTP header of a Web site
+ * by manually entering it in the command-line wallet
+ * **via NFC** (explained in this guide)
+
+ The details of ``taler://`` URIs are specified in `LSD 0006 <https://lsd.gnunet.org/lsd0006/>`_.
+
+3. The wallet processes the ``taler://pay/`` URI. In this example, we use the
+ command-line wallet:
+
+ .. code-block:: console
+
+ # Withdraw some toy money (KUDOS) from the demo bank
+ $ taler-wallet-cli test-withdraw \
+ -e https://exchange.demo.taler.net/ \
+ -b https://bank.demo.taler.net/ \
+ -a KUDOS:10
+ # Pay for the order from the merchant.
+ $ taler-wallet-cli pay-uri 'taler://pay/backend.demo.taler.net/-/-/2019.255-02YDHMXCBQP6J'
+ # [... User is asked to confirm the payment ...]
+
+ .. hint::
+
+ The command-line wallet is typically used by developers and not by end-users.
+ See the :ref:`wallet manual <command-line-wallet>` for installation instructions.
+
+
+4. The merchant checks the payment status again:
+
+ .. code-block:: console
+
+ $ backend_base_url=https://backend.demo.taler.net/
+ $ auth_header='Authorization: ApiKey sandbox'
+ $ curl -XGET -H"$auth_header" \
+ "$backend_base_url/private/orders/2019.255-02YDHMXCBQP6J"
+ # Response:
+ {
+ "paid": true,
+ # ... (some fields omitted)
+ }
+
+ .. note::
+
+ When paying for digital products displayed on a Web site identified by the
+ fulfillment URL, the merchant only needs to check the payment status
+ before responding with the fulfillment page.
+
+ For in-store payments, the merchant must periodically check the payment status.
+ Instead of polling in a busy loop, the ``timeout_ms`` parameter
+ of GET ``/private/orders/$ORDER_ID``
+ should be used.
+
+
+Taler NFC Basics
+================
+
+The NFC communication in GNU Taler follows the ISO-DEP (`ISO 14443-4
+<https://www.iso.org/standard/73599.html>`_) standard. The wallet always acts
+as a tag (or more precisely, emulated card), while the merchant PoS terminal
+and bank terminal act as a reader.
+
+The basic communication unit is the application protocol data unit (`APDU
+<https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit>`_), with the structure
+and commands defined in `ISO 7816 <https://cardwerk.com/iso-7816-smart-card-standard>`_.
+
+The GNU Taler wallet uses the AID (application identifier) ``F00054414c4552``.
+The ``F`` prefix indicates the proprietary/unregistered namespace of AIDs, and
+the rest of the identifier is the hex-encoded ASCII-string ``TALER`` (with one
+0-byte left padding).
+
+During the time that the wallet is paired with a reader, there is state
+associated with the communication channel. Most importantly, the first message
+sent by the reader to the wallet must be a ``SELECT FILE (=0xA4)`` that selects
+the GNU Taler AID. Messages that are sent before the correct ``SELECT FILE``
+message results in implementation-defined behavior, such as the tag disconnecting,
+ignoring the message or an app other than the wallet receiving the message.
+
+The reader sends commands to the wallet with the ``PUT DATA (=0xDA)``
+instruction, using the instruction parameters ``0x0100``, denoting a
+proprietary instruction.
+
+The command data of the ``PUT DATA`` APDU is prefixed by a one-byte Taler
+instruction ID (TID). Currently, the following TIDs are used:
+
+.. list-table::
+ :widths: 5 50
+ :header-rows: 1
+
+ * - TID (reader to wallet)
+ - Description
+ * - ``0x01``
+ - Dereference the UTF-8 encoded ``taler://`` URI in the remainder of the command data.
+ * - ``0x02``
+ - Accept the UTF-8 encoded JSON object in the remainder of the command data as a request tunneling response.
+
+
+The ``GET DATA (=0xCA)`` instruction (again with the instruction parameters
+``0x0100`` is used to request a command from the wallet. The APDU with this
+instruction must be sent with a ``0x0000`` trailer to indicate that up to 65536
+bytes of data are expected in the response from the wallet. Note that the
+wallet itself cannot initiate communication, and thus the reader must "poll"
+the wallet for commands.
+
+The response to the ``GET DATA`` instruction has a Taler instruction ID in the
+first byte. The rest of the
+body is interpreted depending on the TID.
+
+.. list-table::
+ :widths: 15 50
+ :header-rows: 1
+
+ * - TID
+ (wallet to reader)
+ - Description
+ * - ``0x03``
+ - Accept the UTF-8 encoded JSON object in the remainder of the command data as a request tunneling request.
+
+
+Sending taler:// URIs to the Wallet via NFC
+===========================================
+
+To make the wallet process a ``taler://`` URI via NFC, the merchant PoS
+terminal sends a ``SELECT FILE`` command with the GNU Taler AID, and a ``PUT
+DATA`` command with TID ``0x01`` and the URI in the rest
+of the command data.
+
+Here is an example protocol trace from an interaction which caused the wallet
+to dereference the ``taler://pay`` URI from the example above:
+
+.. code-block:: none
+
+ # SELECT FILE
+ m->w 00A4040007F00054414c4552
+ # success response with no data
+ m<-w 9000
+
+ # PUT DATA (TID=0x01)
+ m->w 00DA01007c0174616c65723a2f2f7061792f6261636b656e642e64656d6f2e74
+ 616c65722e6e65742f2d2f2d2f323031392e3235352d30325944484d58434251
+ 50364a
+ # success response with no data
+ m<-w 9000
+
+(Note that this process works analogously for communication with a bank/ATM
+terminal.)
+
+
+Request tunneling
+=================
+
+Request tunneling allows tunneling a (very) restricted subset of HTTP through
+NFC. In particular, only JSON request and response bodies are allowed.
+
+It is currently assumed that the requests and responses fit into one APDU frame.
+For devices with more limited maximum APDU sizes, additional TIDs for segmented
+tunnel requests/responses may be defined in the future.
+
+A request for tunneling is initiated with TID ``0x03`` and responded to with
+TID ``0x02`` (see tables above). A tunneling request is identified by a
+numeric ID, which must be unique during one pairing between reader and tag.
+
+The request tunneling request/response JSON messages have the following schema:
+
+.. code-block:: tsref
+
+ interface TalerRequestTunnelRequest {
+ // Identifier for the request
+ id: number;
+
+ // Request URL
+ url: string;
+
+ // HTTP method to use
+ method: "post" | "get";
+
+ // Request headers
+ headers?: { [name: string]: string };
+
+ // JSON body for the request, only applicable to POST requests
+ body?: object;
+ }
+
+ interface TalerRequestTunnelResponse {
+ // Identifier for the request
+ id: number;
+
+ // Response HTTP status code,
+ // "0" if there was no response.
+ status: number;
+
+ // JSON body of the response, or undefined
+ // if the response wasn't JSON.
+ // May contain error details if 'status==0'
+ body?: object;
+ }