\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename tutorial.info @include ../../common/texi/version.texi @include ../../common/texi/syntax.texi @settitle The GNU Taler tutorial for PHP Web shop developers @value{VERSION} @c Define a new index for options. @defcodeindex op @c Combine everything into one index (arbitrarily chosen to be the @c concept index). @syncodeindex op cp @c %**end of header @copying This tutorial is about implementing a merchant frontend to run against a GNU Taler merchant backend (version @value{VERSION}, @value{UPDATED}), Copyright @copyright{} 2016, 2017, 2018 Taler Systems SA @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end quotation @end copying @c If your tutorial is published on paper by the FSF, it should include @c The standard FSF Front-Cover and Back-Cover Texts, as given in @c maintain.texi. @c @c Titlepage @c @titlepage @title The GNU Taler tutorial for PHP Web shops @subtitle Version @value{VERSION} @subtitle @value{UPDATED} @author Marcello Stanisci (@email{marcello.stanisci@@inria.fr}) @author Christian Grothoff (@email{christian.grothoff@@inria.fr} @author Florian Dold (@email{florian.dold@@inria.fr}) @page @vskip 0pt plus 1filll @insertcopying @end titlepage @summarycontents @contents @ifnottex @node Top @top The GNU Taler tutorial for PHP Web shops @insertcopying @end ifnottex @menu * Introduction:: Whom this tutorial is addressed to * Setting up a simple donation page:: How to set up a donation page * Back-office-integration:: How to integrate with the back office * Advanced topics:: Detailed solutions to specific issues * Reference:: Merchant integration reference Appendices * GNU-LGPL:: The GNU Lesser General Public License says how you can use the code of libtalermerchant.so in your own projects. * GNU-FDL:: The GNU Free Documentation License says how you can copy and share the documentation of GNU Taler. Indices * Concept Index:: Index of concepts and programs. @end menu @node Introduction @chapter Introduction @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). @section About this tutorial This tutorial is for Web developers and addresses how to integrate GNU Taler with Web shops. It describes how to create a Web shop that processes payments with the help of a GNU Taler merchant @emph{backend}. In the second chapter, you will learn how to trigger the payment process from the Web site, how to communicate with the backend, how to generate a order and process the payment. The third chapter covers the integration of a back office with the backend, which includes tracking payments for orders, matching payments to orders, and persisting and retrieving contracts. @cindex examples @cindex git You can download all of the code examples given in this tutorial from @url{https://git.taler.net/merchant-frontend-examples.git/tree/php/}. @section Architecture overview The Taler software stack for a merchant consists of the following main components: @itemize @cindex frontend @item 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. @cindex back office @item A back office application that enables the shop operators to view customer orders, match them to financial transfers, and possibly approve refunds if an order cannot be satisfied. This component is again not included with Taler, but rather assumed to exist at the merchant. This tutorial will describe how to integrate such a component to handle payments managed by Taler. Such integration is shown by adding the back office functionality to the frontend implemented in the second part of this tutorial. @cindex backend @item 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 backend, but for a production deployment a merchant-specific backend will need to be setup by a system administrator. @end itemize The following image illustrates the various interactions of these key components: @image{arch, 3in, 4in} 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. @node Setting up a simple donation page @chapter Setting up a simple donation page This section describes how to setup a simple shop, which exposes a button to get donations via Taler. The expected behaviour is that once the ``donate'' button is clicked, the customer will receive a Taler *proposal* offering him the opportunity to make a fixed donation, for example to donate 1 KUDOS to the charity operating the shop. All the code samples shown below in the tutorial can be found at @url{https://git.taler.net/merchant-frontend-examples.git/tree/php}. @c NOTE: include explaining wallet installation to Web developer here! @c Next sentence is inconsistent with Python version. Why? Note that if the customer does not have the Taler wallet installed, they should instead be prompted to proceed with a classic dialog for credit card payments. @section Specifying the backend @cindex backend @cindex configuration @cindex currency For many critical operations, the frontend needs to communicate with a Taler backend. Assuming that you do not yet have a backend configured, you can use the public backend provided by the Taler project for testing. This public backend has been set-up at @code{http://backend.demo.taler.net/} specifically for testing frontends. It uses the currency ``KUDOS'' and all payments will go into the ``Tutorial'' account at the Taler ``bank'' running at @code{https://bank.demo.taler.net/public-accounts}. To point the frontend being developed in this tutorial to some backend, it suffices to set the variable @code{$BACKEND} in @code{php/config.php} to the desired backend's base URL. You also need to specify the currency used by the backend. For example: @smallexample // php/config.php @verbatiminclude ../config.php @end smallexample @section Talking to the backend @cindex backend Given the above configuration, we can now implement two simple functions @code{get_to_backend} and @code{post_to_backend} to send requests to the backend. The function @code{get_to_backend} is in charge of performing HTTP GET requests to the backend, while @code{post_to_backend} will send HTTP POST requests. @smallexample // php/backend.php @verbatiminclude ../backend.php @end smallexample The given @code{backend.php} code uses a few helper functions from @code{php/helpers.php}, which should be self-explanatory. @node Prompting for payment @section Prompting for payment @cindex button Our goal is to trigger a Taler payment once the customer has clicked on a donation button. We will use a button that issues an HTTP GET to the frontend @code{/donate.php} URL. For this, the HTML would be as follows: @smallexample // php/index.html @verbatiminclude ../index.html @end smallexample When the server-side handler for @code{/donate.php} receives the form submission, it will return a HTML page that will take care of: @itemize @item showing a credit card paywall to the user if no wallet is found, and @item fetching a Taler proposal and passing it to the wallet if one is found @end itemize A minimalistic @code{donate.php} implementation is shown below (in PHP): @cindex pay handler @cindex 402 @cindex X-Taler-Contract-Url @smallexample // php/donate.php @verbatiminclude ../donate.php @end smallexample Given this response, the Taler wallet will fetch the proposal from @url{/generate-order.php} and display it to the user. If the wallet is not present, the HTML body will be shown and the Taler headers and the 402 status code ought to be ignored by the browser. @section A helper function to generate the order We make distinction between @emph{three} different stages of what it informally called "contract". In a very first stage, we call it the @emph{order}: that occurs when the frontend generates the first JSON that misses some information that the backend is supposed to add. When the backend completes the order and signs it, we have a @emph{proposal}. The proposal is what the user is prompted with, and allows them to confirm the purchase. Once the user confirms the purchase, the wallet makes a signature over the proposal, turning it into a @emph{contract}. We first define a helper function @code{make_order} that will generate a complete Taler order as a nested PHP array. The function takes only the order ID and the timestamp as arguments; all of the other details of the order are hardcoded in this simple example. The following code generate a order about donating 1 KUDOS to the 'Taler charity program': @cindex contract @smallexample // php/order.php @verbatiminclude ../order.php @end smallexample @section Signing and returning the proposal The server-side handler for @code{/generate-order.php} has to call @code{make_order} and then POST the result to the backend at @code{/proposal}. By POSTing the order to the backend we get a cryptographic signature over its contents. The result is then returned to the wallet. A simple @code{/generate-order.php} handler may thus look like this: @cindex signature @cindex backend @cindex order @smallexample // php/generate-order.php @verbatiminclude ../generate-order.php @end smallexample @c FIXME: improve example to do this right? Note that in practice the frontend might want to generate a monotonically increasing series of order IDs to avoid a chance of collisions. Order IDs must be in the range of @math{[0:2^{51})}. @section Handling errors In the above example, the helper function @code{build_error} is used to generate an error response in the case that the backend somehow failed to respond properly to our request. The function @code{build_error} is shown below, it returns JSON data matching a particular format for reporting errors, see @code{http://api.taler.net/api-common.html#errordetail}: @smallexample @c FIXME, build_error() doesn't respect error-reporting format yet! // php/error.php @verbatiminclude ../error.php @end smallexample @node Initiating the payment process @section Initiating the payment process @cindex fulfillment URL After the browser has fetched the proposal, the user will be given the opportunity to affirm the payment. Assuming the user affirms, the browser will navigate to the ``fulfillment_url'' that was specified in the proposal. The fulfillment page can be called by users that have already paid for the item, as well as by users that have not yet paid at all. The fulfillment page must thus use the HTTP session state to detect if the payment has been performed already, and if not request payment from the wallet. For our example, the fulfillment URL will contain the order id of the donation, like in the following example: @smallexample https://shop.com/fulfillment.php?order_id= @end smallexample The fulfillment handler at @code{/fulfillment.php} will use this information to check if the user has already paid, and if so confirm the donation. If the user has not yet paid, it will instead return another ``402 Payment Required'' header, requesting the wallet to pay: @smallexample // php/fulfillment.php @verbatiminclude ../fulfillment.php @end smallexample @cindex 402 payment required Here, this second 402 response contains the following Taler-specific headers: @table @code @item X-Taler-Contract-Url @cindex X-Taler-Contract-Url The URL that generated the proposal that led to this payment. The wallet may need to reconstruct the proposal. @item X-Taler-Contract-Query @cindex X-Taler-Contract-Query The way the wallet should lookup for replayable payments. NOTE that for each payment done, the wallet stores the coins it spent for it in an internal database. And each set of used coins is associated to the fulfillment page where they have been spent. So whenever an already known fulfillment page requests a payment, the wallet will pick those coins it spent on that fulfillment page and resend them (therefore @emph{replaying} the payment). In other words, new coins are used only on unknown fulfillment pages. This header is supposed to be removed in future versions of the wallet though, as it only works with the value @code{"fulfillment_url"}. @item X-Taler-Offer-Url @cindex X-Taler-Offer-Url In case that the wallet does not know about this payment already, i.e. because a user shared the URL with another user, this tells the wallet where to go to retrieve a fresh offer. @end table @section Receiving payments via Taler The final next step for the frontend is to accept the payment from the wallet. For this, the frontend must implement a payment handler at the URI specified in the @code{pay_url} proposal field, as explained above. The role of the @code{/pay.php} handler is to receive the payment from the wallet and forward it to the backend. If the backend reports that the payment was successful, the handler needs to update the session state with the browser to remember that the user paid. The following code implements this in PHP: @smallexample // php/pay.php @verbatiminclude ../pay.php @end smallexample Do not be confused by the @code{isset} test for the session state. In our simple example, it will be set to ``false'' by the fulfillment URL which the browser actually always visits first. After the @code{pay.php} handler has affirmed that the payment was successful, the wallet will refresh the fulfillment page, this time receiving the message that the donation was successful. If anything goes wrong, the wallet will handle the respective error. @node Back-office-integration @chapter Integration with the back office Taler ships the back-office feature as a stand-alone Web application. See how to run it, on its own documentaion: @url{https://docs.taler.net/backoffice/html/manual.html}. @node Advanced topics @chapter Advanced topics @menu * Detecting the presence of the Taler wallet:: Detecting the presence of the Taler wallet * The Taler proposal format:: The Taler proposal format * Instances:: Instances * The fulfillment page:: The fulfillment page * Normalized base URLs:: Normalized base URLs @end menu @include ../../common/texi/wallet-detection.texi @include ../../common/texi/proposals.texi @include ../../common/texi/instances.texi @include ../../common/texi/fulfillment-page.texi @include ../../common/texi/normalized-base-url.texi @c ************ Reference chapter *********** @include ../../common/texi/api-reference.texi @c ********************************************************** @c ******************* Appendices ************************* @c ********************************************************** @node GNU-LGPL @unnumbered GNU-LGPL @cindex license @cindex LGPL @include ../../common/texi/lgpl.texi @node GNU-FDL @unnumbered GNU-FDL @cindex license @cindex GNU Free Documentation License @include ../../common/texi/fdl-1.3.texi @node Concept Index @unnumbered Concept Index @printindex cp @bye