From 12f0c8ca6c907850aa0457a5ddbdc4640a3b7a33 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 18 Sep 2019 19:06:49 +0200 Subject: prebuilt: update --- texinfo/taler-merchant-api-tutorial.texi | 945 +++++++++++++++++++++++++++++++ 1 file changed, 945 insertions(+) create mode 100644 texinfo/taler-merchant-api-tutorial.texi (limited to 'texinfo/taler-merchant-api-tutorial.texi') 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"@}) + +@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"@}) + +@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"@}) + +@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"@}) + +@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"@}) + +@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 + + + + Tutorial + + + +

+ No wallet found. +

+

+ Wallet found! +

+ + +@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 -- cgit v1.2.3