summaryrefslogtreecommitdiff
path: root/texinfo/taler-merchant-api-tutorial.texi
diff options
context:
space:
mode:
Diffstat (limited to 'texinfo/taler-merchant-api-tutorial.texi')
-rw-r--r--texinfo/taler-merchant-api-tutorial.texi945
1 files changed, 945 insertions, 0 deletions
diff --git a/texinfo/taler-merchant-api-tutorial.texi b/texinfo/taler-merchant-api-tutorial.texi
new file mode 100644
index 00000000..b49eeefe
--- /dev/null
+++ b/texinfo/taler-merchant-api-tutorial.texi
@@ -0,0 +1,945 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename taler-merchant-api-tutorial.info
+@documentencoding UTF-8
+@ifinfo
+@*Generated by Sphinx 2.2.0.@*
+@end ifinfo
+@settitle Taler Merchant API Tutorial
+@defindex ge
+@paragraphindent 0
+@exampleindent 4
+@finalout
+@dircategory CATEGORY
+@direntry
+* MENU ENTRY: (taler-merchant-api-tutorial.info). DESCRIPTION
+@end direntry
+
+@definfoenclose strong,`,'
+@definfoenclose emph,`,'
+@c %**end of header
+
+@copying
+@quotation
+GNU Taler 0.6.0pre1, Sep 18, 2019
+
+GNU Taler team
+
+Copyright @copyright{} 2014, 2015, 2016 Florian Dold, Benedikt Muller, Sree Harsha Totakura, Christian Grothoff, Marcello Stanisci (GPLv3+ or GFDL 1.3+)
+@end quotation
+
+@end copying
+
+@titlepage
+@title Taler Merchant API Tutorial
+@insertcopying
+@end titlepage
+@contents
+
+@c %** start of user preamble
+
+@c %** end of user preamble
+
+@ifnottex
+@node Top
+@top Taler Merchant API Tutorial
+@insertcopying
+@end ifnottex
+
+@c %**start of body
+@anchor{taler-merchant-api-tutorial doc}@anchor{0}
+@menu
+* Introduction::
+* Accepting a Simple Payment::
+* Giving Refunds::
+* Giving Customers Tips::
+* Advanced topics::
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Introduction
+
+* About GNU Taler::
+* About this tutorial::
+* Architecture overview::
+* Public Sandbox Backend and Authentication::
+* Merchant Instances::
+
+Accepting a Simple Payment
+
+* Creating an Order for a Payment::
+* Checking Payment Status and Prompting for Payment::
+
+Advanced topics
+
+* Detecting the Presence of the Taler Wallet::
+* Integration with the Back Office::
+* Session-Bound Payments::
+* Product Identification::
+* The Taler Order Format::
+
+Detecting the Presence of the Taler Wallet
+
+* Presence detection without JavaScript::
+* Detection with JavaScript::
+
+@end detailmenu
+@end menu
+
+@node Introduction,Accepting a Simple Payment,Top,Top
+@anchor{taler-merchant-api-tutorial gnu-taler-merchant-api-tutorial}@anchor{1}@anchor{taler-merchant-api-tutorial introduction}@anchor{2}
+@chapter Introduction
+
+
+@menu
+* About GNU Taler::
+* About this tutorial::
+* Architecture overview::
+* Public Sandbox Backend and Authentication::
+* Merchant Instances::
+
+@end menu
+
+@node About GNU Taler,About this tutorial,,Introduction
+@anchor{taler-merchant-api-tutorial about-gnu-taler}@anchor{3}
+@section About GNU Taler
+
+
+GNU Taler is an open protocol for an electronic payment system with a
+free software reference implementation. GNU Taler offers secure, fast
+and easy payment processing using well understood cryptographic
+techniques. GNU Taler allows customers to remain anonymous, while
+ensuring that merchants can be held accountable by governments. Hence,
+GNU Taler is compatible with anti-money-laundering (AML) and
+know-your-customer (KYC) regulation, as well as data protection
+regulation (such as GDPR).
+
+@node About this tutorial,Architecture overview,About GNU Taler,Introduction
+@anchor{taler-merchant-api-tutorial about-this-tutorial}@anchor{4}
+@section About this tutorial
+
+
+This tutorial addresses how to process payments using the GNU Taler
+merchant Backend. 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
+requests library for HTTP requests. Versions for other
+languages/environments are available as well.
+
+If you want to look at some simple, running examples, check out these:
+
+
+@itemize -
+
+@item
+The essay merchant@footnote{https://git.taler.net/blog.git/tree/talerblog/blog/blog.py}
+that sells single chapters of a book.
+
+@item
+The donation page@footnote{https://git.taler.net/donations.git/tree/talerdonations/donations/donations.py}
+that accepts donations for software projects and gives donation
+receipts.
+
+@item
+The
+survey@footnote{https://git.taler.net/survey.git/tree/talersurvey/survey/survey.py}
+that gives users who answer a question a small reward.
+@end itemize
+
+@node Architecture overview,Public Sandbox Backend and Authentication,About this tutorial,Introduction
+@anchor{taler-merchant-api-tutorial architecture-overview}@anchor{5}
+@section Architecture overview
+
+
+The Taler software stack for a merchant consists of the following main
+components:
+
+
+@itemize -
+
+@item
+frontend
+A frontend which interacts with the customer’s browser. The frontend
+enables the customer to build a shopping cart and place an order.
+Upon payment, it triggers the respective business logic to satisfy
+the order. This component is not included with Taler, but rather
+assumed to exist at the merchant. This tutorial describes how to
+develop a Taler frontend.
+
+@item
+backend
+A Taler-specific payment backend which makes it easy for the frontend
+to process financial transactions with Taler. For this tutorial, you
+will use a public sandbox backend. For production use, you must
+either set up your own backend or ask another person to do so for
+you.
+@end itemize
+
+The following image illustrates the various interactions of these key
+components:
+
+
+@image{taler-merchant-api-tutorial-figures/arch-api,,,image0,png}
+
+
+The backend provides the cryptographic protocol support, stores
+Taler-specific financial information and communicates with the GNU Taler
+exchange over the Internet. The frontend accesses the backend via a
+RESTful API. As a result, the frontend never has to directly communicate
+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 @code{/public/}.
+
+@node Public Sandbox Backend and Authentication,Merchant Instances,Architecture overview,Introduction
+@anchor{taler-merchant-api-tutorial public-sandbox-backend-and-authentication}@anchor{6}
+@section Public Sandbox Backend and Authentication
+
+
+sandbox
+authorization
+How the frontend authenticates to the Taler backend depends on the
+configuration. See Taler Merchant Operating Manual.
+
+The public sandbox backend @indicateurl{https://backend.demo.taler.net/} uses an API
+key in the @code{Authorization} header. The value of this header must be
+@code{ApiKey sandbox} for the public sandbox backend.
+
+@example
+>>> import requests
+>>> requests.get("https://backend.demo.taler.net",
+... headers=@{"Authorization": "ApiKey sandbox"@})
+<Response [200]>
+@end example
+
+If an HTTP status code other than 200 is returned, something went wrong.
+You should figure out what the problem is before continuing with this
+tutorial.
+
+The sandbox backend @indicateurl{https://backend.demo.taler.net/} uses @code{KUDOS} as an
+imaginary currency. Coins denominated in @code{KUDOS} can be withdrawn from
+@indicateurl{https://bank.demo.taler.net/}.
+
+@node Merchant Instances,,Public Sandbox Backend and Authentication,Introduction
+@anchor{taler-merchant-api-tutorial merchant-instances}@anchor{7}
+@section Merchant Instances
+
+
+instance
+The same Taler merchant backend server can be used by multiple separate
+merchants that are separate business entities. Each of these separate
+business entities is called a @emph{merchant instance}, and is identified by
+an alphanumeric @emph{instance id}. If the instance is omitted, the instance
+id @code{default} is assumed.
+
+The following merchant instances are configured on
+@indicateurl{https://backend.demo.taler.net/}:
+
+
+@itemize -
+
+@item
+@code{GNUnet} (The GNUnet project)
+
+@item
+@code{FSF} (The Free Software Foundation)
+
+@item
+@code{Tor} (The Tor Project)
+
+@item
+@code{default} (Kudos Inc.)
+@end itemize
+
+Note that these are fictional merchants used for our demonstrators and
+not affiliated with or officially approved by the respective projects.
+
+@node Accepting a Simple Payment,Giving Refunds,Introduction,Top
+@anchor{taler-merchant-api-tutorial accepting-a-simple-payment}@anchor{8}@anchor{taler-merchant-api-tutorial id1}@anchor{9}
+@chapter Accepting a Simple Payment
+
+
+@menu
+* Creating an Order for a Payment::
+* Checking Payment Status and Prompting for Payment::
+
+@end menu
+
+@node Creating an Order for a Payment,Checking Payment Status and Prompting for Payment,,Accepting a Simple Payment
+@anchor{taler-merchant-api-tutorial creating-an-order-for-a-payment}@anchor{a}
+@section Creating an Order for a Payment
+
+
+order
+Payments in Taler revolve around an @emph{order}, which is a machine-readable
+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 @code{/order} API
+endpoint. At least the following fields must be given:
+
+
+@itemize -
+
+@item
+amount: The amount to be paid, as a string in the format
+@code{CURRENCY:DECIMAL_VALUE}, for example @code{EUR:10} for 10 Euros or
+@code{KUDOS:1.5} for 1.5 KUDOS.
+
+@item
+summary: A human-readable summary for what the payment is about. The
+summary should be short enough to fit into titles, though no hard
+limit is enforced.
+
+@item
+fulfillment_url: A URL that will be displayed once the payment is
+completed. For digital goods, this should be a page that displays the
+product that was purchased. On successful payment, the wallet
+automatically appends the @code{order_id} as a query parameter, as well
+as the @code{session_sig} for session-bound payments (discussed later).
+@end itemize
+
+Orders can have many more fields, see @ref{b,,The Taler Order Format}.
+
+After successfully @code{POST}ing to @code{/order}, an @code{order_id} will be
+returned. Together with the merchant @code{instance}, the order id uniquely
+identifies the order within a merchant backend.
+
+@example
+>>> import requests
+>>> order = dict(order=dict(amount="KUDOS:10",
+... summary="Donation",
+... fulfillment_url="https://example.com/thanks.html"))
+>>> order_resp = requests.post("https://backend.demo.taler.net/order", json=order,
+... headers=@{"Authorization": "ApiKey sandbox"@})
+<Response [200]>
+@end example
+
+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
+@emph{contract terms}. contract terms
+
+@node Checking Payment Status and Prompting for Payment,,Creating an Order for a Payment,Accepting a Simple Payment
+@anchor{taler-merchant-api-tutorial checking-payment-status-and-prompting-for-payment}@anchor{c}
+@section Checking Payment Status and Prompting for Payment
+
+
+The status of a payment can be checked with the @code{/check-payment}
+endpoint. If the payment is yet to be completed by the customer,
+@code{/check-payment} will give the frontend a URL (the
+payment_redirect_url) that will trigger the customer’s wallet to execute
+the payment.
+
+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
+yet.
+
+@example
+>>> import requests
+>>> r = requests.get("https://backend.demo.taler.net/check-payment",
+... params=dict(order_id=order_resp.json()["order_id"]),
+... headers=@{"Authorization": "ApiKey sandbox"@})
+>>> print(r.json())
+@end example
+
+If the paid field in the response is @code{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:
+
+
+@itemize -
+
+@item
+paid: Set to true.
+
+@item
+contract_terms: The full contract terms of the order.
+
+@item
+refunded: @code{true} if a (possibly partial) refund was granted for
+this purchase.
+
+@item
+refunded_amount: Amount that was refunded
+
+@item
+last_session_id: Last session ID used by the customer’s wallet. See
+@ref{d,,Session-Bound Payments}.
+@end itemize
+
+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.
+
+@node Giving Refunds,Giving Customers Tips,Accepting a Simple Payment,Top
+@anchor{taler-merchant-api-tutorial giving-refunds}@anchor{e}@anchor{taler-merchant-api-tutorial id2}@anchor{f}
+@chapter Giving Refunds
+
+
+refunds
+A refund in GNU Taler is a way to “undo” a payment. It needs to be
+authorized by the merchant. Refunds can be for any fraction of the
+original amount paid, but they cannot exceed the original payment.
+Refunds are time-limited and can only happen while the exchange holds
+funds for a particular payment in escrow. The time during which a refund
+is possible can be controlled by setting the @code{refund_deadline} in an
+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
+@code{POST}ing to the @code{/refund} endpoint.
+
+The refund request JSON object has the following fields:
+
+
+@itemize -
+
+@item
+order_id: Identifies for which order a customer should be refunded.
+
+@item
+instance: Merchant instance to use.
+
+@item
+refund: Amount to be refunded. If a previous refund was authorized
+for the same order, the new amount must be higher, otherwise the
+operation has no effect. The value indicates the total amount to be
+refunded, @emph{not} an increase in the refund.
+
+@item
+reason: Human-readable justification for the refund. The reason is
+only used by the Back Office and is not exposed to the customer.
+@end itemize
+
+If the request is successful (indicated by HTTP status code 200), the
+response includes a @code{refund_redirect_url}. The frontend must redirect
+the customer’s browser to that URL to allow the refund to be processed
+by the wallet.
+
+This code snipped illustrates giving a refund:
+
+@example
+>>> import requests
+>>> refund_req = dict(order_id="2018.058.21.46.06-024C85K189H8P",
+... refund="KUDOS:10",
+... instance="default",
+... reason="Customer did not like the product")
+>>> requests.post("https://backend.demo.taler.net/refund", json=refund_req,
+... headers=@{"Authorization": "ApiKey sandbox"@})
+<Response [200]>
+@end example
+
+@node Giving Customers Tips,Advanced topics,Giving Refunds,Top
+@anchor{taler-merchant-api-tutorial giving-customers-tips}@anchor{10}@anchor{taler-merchant-api-tutorial id3}@anchor{11}
+@chapter Giving Customers Tips
+
+
+tips
+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
+that tips are not enforceable for the visitor, as there is no contract.
+It is simply a voluntary gesture of appreciation of the site to its
+visitor. However, once a tip has been granted, the visitor obtains full
+control over the funds provided by the site.
+
+The “merchant” backend of the site must be properly configured for
+tipping, and sufficient funds must be made available for tipping See
+Taler Merchant Operating Manual.
+
+To check if tipping is configured properly and if there are sufficient
+funds available for tipping, query the @code{/tip-query} endpoint:
+
+@example
+>>> import requests
+>>> requests.get("https://backend.demo.taler.net/tip-query?instance=default",
+... headers=@{"Authorization": "ApiKey sandbox"@})
+<Response [200]>
+@end example
+
+authorize tip
+To authorize a tip, @code{POST} to @code{/tip-authorize}. The following fields
+are recognized in the JSON request object:
+
+
+@itemize -
+
+@item
+amount: Amount that should be given to the visitor as a tip.
+
+@item
+instance: Merchant instance that grants the tip (each instance may
+have its own independend tipping funds configured).
+
+@item
+justification: Description of why the tip was granted. Human-readable
+text not exposed to the customer, but used by the Back Office.
+
+@item
+next_url: The URL that the user’s browser should be redirected to by
+the wallet, once the tip has been processed.
+@end itemize
+
+The response from the backend contains a @code{tip_redirect_url}. The
+customer’s browser must be redirected to this URL for the wallet to pick
+up the tip. pick up tip
+
+This code snipped illustrates giving a tip:
+
+@example
+>>> import requests
+>>> tip_req = dict(amount="KUDOS:0.5",
+... instance="default",
+... justification="User filled out survey",
+... next_url="https://merchant.com/thanks.html")
+>>> requests.post("https://backend.demo.taler.net/tip-authorize", json=tip_req,
+... headers=@{"Authorization": "ApiKey sandbox"@})
+<Response [200]>
+@end example
+
+@node Advanced topics,,Giving Customers Tips,Top
+@anchor{taler-merchant-api-tutorial advanced-topics}@anchor{12}@anchor{taler-merchant-api-tutorial id4}@anchor{13}
+@chapter Advanced topics
+
+
+@menu
+* Detecting the Presence of the Taler Wallet::
+* Integration with the Back Office::
+* Session-Bound Payments::
+* Product Identification::
+* The Taler Order Format::
+
+@end menu
+
+@node Detecting the Presence of the Taler Wallet,Integration with the Back Office,,Advanced topics
+@anchor{taler-merchant-api-tutorial detecting-the-presence-of-the-taler-wallet}@anchor{14}@anchor{taler-merchant-api-tutorial id5}@anchor{15}
+@section 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.
+
+@menu
+* Presence detection without JavaScript::
+* Detection with JavaScript::
+
+@end menu
+
+@node Presence detection without JavaScript,Detection with JavaScript,,Detecting the Presence of the Taler Wallet
+@anchor{taler-merchant-api-tutorial presence-detection-without-javascript}@anchor{16}
+@subsection 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 @code{link}
+tag with the @code{id} attribute set to @code{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:
+
+
+@table @asis
+
+@item @code{taler-installed-hide}
+
+A CSS rule will set the @code{display} property for this class to
+@code{none} once the Taler wallet is installed and enabled. If the
+wallet is not installed, @code{display} will be @code{inherit}.
+
+@item @code{taler-installed-show}
+
+A CSS rule will set the @code{display} property for this class to
+@code{inherit} once the Taler wallet is installed and enabled. If the
+wallet is not installed, @code{display} will be @code{none}.
+@end table
+
+The following is a complete example:
+
+@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>
+@end example
+
+The @code{taler-fallback.css} is part of the Taler’s @emph{web-common}
+repository, available at
+@indicateurl{https://git.taler.net/web-common.git/tree/taler-fallback.css}. You may
+have to adjust the @code{href} attribute in the HTML code above to point to
+the correct location of the @code{taler-fallback.css} file on your Web
+site.
+
+@node Detection with JavaScript,,Presence detection without JavaScript,Detecting the Presence of the Taler Wallet
+@anchor{taler-merchant-api-tutorial detection-with-javascript}@anchor{17}
+@subsection Detection with JavaScript
+
+
+The following functions are defined in the @code{taler} namespace of the
+@code{taler-wallet-lib} helper library available at
+@indicateurl{https://git.taler.net/web-common.git/tree/taler-wallet-lib.js}.
+
+
+@table @asis
+
+@item @code{onPresent(callback: () => void)}
+
+Adds a callback to be called when support for Taler payments is
+detected.
+
+@item @code{onAbsent(callback: () => void)}
+
+Adds a callback to be called when support for Taler payments is
+disabled.
+@end table
+
+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.
+
+@node Integration with the Back Office,Session-Bound Payments,Detecting the Presence of the Taler Wallet,Advanced topics
+@anchor{taler-merchant-api-tutorial id6}@anchor{18}@anchor{taler-merchant-api-tutorial integration-with-the-back-office}@anchor{19}
+@section 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
+@indicateurl{https://docs.taler.net/backoffice/html/manual.html}.
+
+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
+@indicateurl{https://docs.taler.net/api/api-merchant.html}
+
+@node Session-Bound Payments,Product Identification,Integration with the Back Office,Advanced topics
+@anchor{taler-merchant-api-tutorial session-002dbound-payments}@anchor{1a}@anchor{taler-merchant-api-tutorial session-bound-payments}@anchor{1b}
+@section Session-Bound Payments
+
+
+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
+this model by allowing the mechant to check whether the “payment
+receipt” is available on the user’s current device. This prevents users
+from easily sharing media access by transmitting a link to the
+fulfillment page. Of course sophisticated users could share payment
+receipts as well, but this is not as easy as sharing a link, and in this
+case they are more likely to just share the media directly.
+
+To use this feature, the merchant must first assign the user’s current
+browser an ephemeral @code{session_id}, usually via a session cookie. When
+executing or re-playing a payment, the wallet will receive an additional
+signature (@code{session_sig}). This signature certifies that the wallet
+showed a payment receipt for the respective order in the current
+session. cookie
+
+Session-bound payments are triggerd by passing the @code{session_id}
+parameter to the @code{/check-payment} endpoint. The wallet will then
+redirect to the fulfillment page, but include an additional
+@code{session_sig} parameter. The frontend can query @code{/check-payment}
+with both the @code{session_id} and the @code{session_sig} to verify that the
+signature is correct.
+
+The last session ID that was successfuly used to prove that the payment
+receipt is in the user’s wallet is also available as @code{last_session_id}
+in the response to @code{/check-payment}.
+
+@node Product Identification,The Taler Order Format,Session-Bound Payments,Advanced topics
+@anchor{taler-merchant-api-tutorial id7}@anchor{1c}@anchor{taler-merchant-api-tutorial product-identification}@anchor{1d}
+@section Product Identification
+
+
+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
+shops without a login system. In this case, the user would be prompted
+for payment again, even though they already purchased the product.
+
+To allow the wallet to instead find the existing payment receipt, the
+shop must use a unique fulfillment URL for each product. Then, the
+frontend must provide an additional @code{resource_url} parameter to to
+@code{/check-payment}. It should identify this unique fulfillment URL for
+the product. The wallet will then check whether it has paid for a
+contract with the same @code{resource_url} before, and if so replay the
+previous payment.
+
+@node The Taler Order Format,,Product Identification,Advanced topics
+@anchor{taler-merchant-api-tutorial id8}@anchor{1e}@anchor{taler-merchant-api-tutorial the-taler-order-format}@anchor{1f}
+@section The Taler Order Format
+
+
+A Taler order can specify many details about the payment. This section
+describes each of the fields in depth.
+
+Financial amounts are always specified as a string in the format
+@code{"CURRENCY:DECIMAL_VALUE"}.
+
+
+@table @asis
+
+@item amount
+
+amount
+Specifies the total amount to be paid to the merchant by the
+customer.
+
+@item max_fee
+
+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.
+
+@item max_wire_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.
+
+@item wire_fee_amortization
+
+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
+the expected customer’s contribution to the wire fee. The customer’s
+contribution may further be reduced by the difference between the
+’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.
+
+@item pay_url
+
+pay_url
+Which URL accepts payments. This is the URL where the wallet will
+POST coins.
+
+@item fulfillment_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.
+
+@item order_id
+
+order ID
+Alphanumeric identifier, freely definable by the merchant. Used by
+the merchant to uniquely identify the transaction.
+
+@item summary
+
+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.
+
+@item timestamp
+
+Time at which the offer was generated.
+
+@item pay_deadline
+
+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
+contracts are past the refund_deadline and execute one large wire
+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.
+
+@item refund_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.
+
+@item products
+
+product description
+Array of products that are being sold to the customer. Each entry
+contains a tuple with the following values:
+
+
+@table @asis
+
+@item description
+
+Description of the product.
+
+@item quantity
+
+Quantity of the items to be shipped. May specify a unit (@code{1 kg})
+or just the count.
+
+@item price
+
+Price for quantity units of this product shipped to the given
+delivery_location. Note that usually the sum of all of the prices
+should add up to the total amount of the contract, but it may be
+different due to discounts or because individual prices are
+unavailable.
+
+@item product_id
+
+Unique ID of the product in the merchant’s catalog. Can generally
+be chosen freely as it only has meaning for the merchant, but
+should be a number in the range @math{[0@comma{}2^@{51@})}.
+
+@item taxes
+
+Map of applicable taxes to be paid by the merchant. The label is
+the name of the tax, i.e. VAT, sales tax or income tax, and the
+value is the applicable tax amount. Note that arbitrary labels are
+permitted, as long as they are used to identify the applicable tax
+regime. Details may be specified by the regulator. This is used to
+declare to the customer which taxes the merchant intends to pay,
+and can be used by the customer as a receipt. The information is
+also likely to be used by tax audits of the merchant.
+
+@item delivery_date
+
+Time by which the product is to be delivered to the
+delivery_location.
+
+@item delivery_location
+
+This should give a label in the locations map, specifying where
+the item is to be delivered.
+@end table
+
+Values can be omitted if they are not applicable. For example, if a
+purchase is about a bundle of products that have no individual prices
+or product IDs, the product_id or price may not be specified in the
+contract. Similarly, for virtual products delivered directly via the
+fulfillment URI, there is no delivery location.
+
+@item merchant
+
+
+@table @asis
+
+@item address
+
+This should give a label in the locations map, specifying where
+the merchant is located.
+
+@item name
+
+This should give a human-readable name for the merchant’s
+business.
+
+@item jurisdiction
+
+This should give a label in the locations map, specifying the
+jurisdiction under which this contract is to be arbitrated.
+@end table
+
+@item locations
+
+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
+same location is required many times (such as the business address of
+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:
+
+
+@table @asis
+
+@item country
+
+Name of the country for delivery, as found on a postal package,
+i.e. “France”.
+
+@item state
+
+Name of the state for delivery, as found on a postal package, i.e.
+“NY”.
+
+@item region
+
+Name of the region for delivery, as found on a postal package.
+
+@item province
+
+Name of the province for delivery, as found on a postal package.
+
+@item city
+
+Name of the city for delivery, as found on a postal package.
+
+@item ZIP code
+
+ZIP code for delivery, as found on a postal package.
+
+@item street
+
+Street name for delivery, as found on a postal package.
+
+@item street number
+
+Street number (number of the house) for delivery, as found on a
+postal package.
+@end table
+
+name receiver name for delivery, either business or person name.
+
+Note that 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.
+@end table
+@anchor{taler-merchant-api-tutorial The-Taler-Order-Format}@w{ }
+@anchor{d}@w{ }
+@anchor{b}@w{ }
+@anchor{taler-merchant-api-tutorial Session_002dBound-Payments}@w{ }
+
+@c %**end of body
+@bye