merchant-frontend-examples

ZZZ: Inactive/Deprecated
Log | Files | Refs

tutorial.texi (16742B)


      1 \input texinfo @c -*-texinfo-*-
      2 @c %**start of header
      3 @setfilename tutorial.info
      4 @include ../../common/texi/version.texi
      5 @include ../../common/texi/syntax.texi
      6 @settitle The GNU Taler tutorial for PHP Web shop developers @value{VERSION}
      7 
      8 @c Define a new index for options.
      9 @defcodeindex op
     10 @c Combine everything into one index (arbitrarily chosen to be the
     11 @c concept index).
     12 @syncodeindex op cp
     13 @c %**end of header
     14 
     15 @copying
     16 This tutorial is about implementing a merchant frontend to run against a
     17 GNU Taler merchant backend (version @value{VERSION}, @value{UPDATED}),
     18 
     19 Copyright @copyright{} 2016, 2017, 2018 Taler Systems SA
     20 
     21 @quotation
     22 Permission is granted to copy, distribute and/or modify this document
     23 under the terms of the GNU Free Documentation License, Version 1.3 or
     24 any later version published by the Free Software Foundation; with no
     25 Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
     26 Texts.  A copy of the license is included in the section entitled
     27 ``GNU Free Documentation License''.
     28 @end quotation
     29 @end copying
     30 @c If your tutorial is published on paper by the FSF, it should include
     31 @c The standard FSF Front-Cover and Back-Cover Texts, as given in
     32 @c maintain.texi.
     33 @c
     34 @c Titlepage
     35 @c
     36 @titlepage
     37 @title The GNU Taler tutorial for PHP Web shops
     38 @subtitle Version @value{VERSION}
     39 @subtitle @value{UPDATED}
     40 @author Marcello Stanisci (@email{marcello.stanisci@@inria.fr})
     41 @author Christian Grothoff (@email{christian.grothoff@@inria.fr}
     42 @author Florian Dold (@email{florian.dold@@inria.fr})
     43 @page
     44 @vskip 0pt plus 1filll
     45 @insertcopying
     46 @end titlepage
     47 
     48 @summarycontents
     49 @contents
     50 
     51 @ifnottex
     52 @node Top
     53 @top The GNU Taler tutorial for PHP Web shops
     54 @insertcopying
     55 @end ifnottex
     56 
     57 @menu
     58 * Introduction::                          Whom this tutorial is addressed to
     59 * Setting up a simple donation page::     How to set up a donation page
     60 * Back-office-integration::               How to integrate with the back office
     61 * Advanced topics::                       Detailed solutions to specific issues
     62 * Reference::                             Merchant integration reference
     63 
     64 
     65 Appendices
     66 
     67 * GNU-LGPL::                     The GNU Lesser General Public License says how you
     68                                  can use the code of libtalermerchant.so in your own projects.
     69 * GNU-FDL::                      The GNU Free Documentation License says how you
     70                                  can copy and share the documentation of GNU Taler.
     71 
     72 Indices
     73 
     74 * Concept Index::               Index of concepts and programs.
     75 @end menu
     76 
     77 
     78 @node Introduction
     79 @chapter Introduction
     80 
     81 @section About GNU Taler
     82 
     83 GNU Taler is an open protocol for an electronic payment system with a
     84 free software reference implementation.  GNU Taler offers secure, fast
     85 and easy payment processing using well understood cryptographic
     86 techniques.  GNU Taler allows customers to remain anonymous, while
     87 ensuring that merchants can be held accountable by governments.
     88 Hence, GNU Taler is compatible with anti-money-laundering (AML) and
     89 know-your-customer (KYC) regulation, as well as data protection
     90 regulation (such as GDPR).
     91 
     92 
     93 @section About this tutorial
     94 
     95 This tutorial is for Web developers and addresses how to integrate GNU
     96 Taler with Web shops. It describes how to create a Web shop that
     97 processes payments with the help of a GNU Taler merchant
     98 @emph{backend}.  In the second chapter, you will learn how to trigger
     99 the payment process from the Web site, how to communicate with the
    100 backend, how to generate a order and process the payment.  The
    101 third chapter covers the integration of a back office with the
    102 backend, which includes tracking payments for orders, matching
    103 payments to orders, and persisting and retrieving contracts.
    104 
    105 @cindex examples
    106 @cindex git
    107 You can download all of the code examples given in this tutorial from
    108 @url{https://git.taler.net/merchant-frontend-examples.git/tree/php/}.
    109 
    110 
    111 @section Architecture overview
    112 
    113 The Taler software stack for a merchant consists of the following
    114 main components:
    115 
    116 @itemize
    117 @cindex frontend
    118 @item A frontend which interacts with the customer's browser. The
    119   frontend enables the customer to build a shopping cart and place
    120   an order.  Upon payment, it triggers the respective business logic
    121   to satisfy the order.  This component is not included with Taler,
    122   but rather assumed to exist at the merchant. This tutorial
    123   describes how to develop a Taler frontend.
    124 @cindex back office
    125 @item A back office application that enables the shop operators to
    126   view customer orders, match them to financial transfers, and possibly
    127   approve refunds if an order cannot be satisfied.  This component is
    128   again not included with Taler, but rather assumed to exist at the
    129   merchant. This tutorial will describe how to integrate such a component
    130   to handle payments managed by Taler.  Such integration is shown by
    131   adding the back office functionality to the frontend implemented
    132   in the second part of this tutorial.
    133 @cindex backend
    134 @item A Taler-specific payment backend which makes it easy for the
    135   frontend to process financial transactions with Taler.  For this
    136   tutorial, you will use a public backend, but for a production
    137   deployment a merchant-specific backend will need to be setup
    138   by a system administrator.
    139 @end itemize
    140 
    141 The following image illustrates the various interactions of these
    142 key components:
    143 
    144 @image{arch, 3in, 4in}
    145 
    146 
    147 The backend provides the cryptographic protocol support,
    148 stores Taler-specific financial information and communicates
    149 with the GNU Taler exchange over the Internet.  The frontend accesses
    150 the backend via a RESTful API.  As a result, the frontend never has to
    151 directly communicate with the exchange, and also does not deal with
    152 sensitive data.  In particular, the merchant's signing keys and bank
    153 account information are encapsulated within the Taler backend.
    154 
    155 @node Setting up a simple donation page
    156 @chapter Setting up a simple donation page
    157 
    158 This section describes how to setup a simple shop, which exposes a
    159 button to get donations via Taler. The expected behaviour is that once
    160 the ``donate'' button is clicked, the customer will receive a Taler
    161 *proposal* offering him the opportunity to make a fixed donation,
    162 for example to donate 1 KUDOS to the charity operating the shop.
    163 
    164 All the code samples shown below in the tutorial can be found at
    165 @url{https://git.taler.net/merchant-frontend-examples.git/tree/php}.
    166 
    167 @c NOTE: include explaining wallet installation to Web developer here!
    168 
    169 @c Next sentence is inconsistent with Python version. Why?
    170 Note that if the customer does not have the Taler wallet installed,
    171 they should instead be prompted to proceed with a classic dialog for
    172 credit card payments.
    173 
    174 
    175 @section Specifying the backend
    176 
    177 @cindex backend
    178 @cindex configuration
    179 @cindex currency
    180 For many critical operations, the frontend needs to communicate
    181 with a Taler backend.  Assuming that you do not yet have a backend
    182 configured, you can use the public backend provided by the Taler
    183 project for testing.  This public backend has been set-up at
    184 @code{http://backend.demo.taler.net/} specifically for testing
    185 frontends.  It uses the currency ``KUDOS'' and all payments will
    186 go into the ``Tutorial'' account at the Taler ``bank'' running at
    187 @code{https://bank.demo.taler.net/public-accounts}.
    188 
    189 To point the frontend being developed in this tutorial to some
    190 backend, it suffices to set the variable @code{$BACKEND} in
    191 @code{php/config.php} to the desired backend's base URL.  You also
    192 need to specify the currency used by the backend.  For example:
    193 
    194 @smallexample
    195 // php/config.php
    196 @verbatiminclude ../config.php
    197 @end smallexample
    198 
    199 
    200 @section Talking to the backend
    201 
    202 @cindex backend
    203 Given the above configuration, we can now implement two simple
    204 functions @code{get_to_backend} and @code{post_to_backend} to
    205 send requests to the backend.  The function @code{get_to_backend}
    206 is in charge of performing HTTP GET requests to the backend,
    207 while @code{post_to_backend} will send HTTP POST requests.
    208 
    209 @smallexample
    210 // php/backend.php
    211 @verbatiminclude ../backend.php
    212 @end smallexample
    213 
    214 The given @code{backend.php} code uses a few helper functions from
    215 @code{php/helpers.php}, which should be self-explanatory.
    216 
    217 
    218 @node Prompting for payment
    219 @section Prompting for payment
    220 
    221 @cindex button
    222 Our goal is to trigger a Taler payment once the customer has clicked
    223 on a donation button.  We will use a button that issues an HTTP GET
    224 to the frontend @code{/donate.php} URL.  For this, the HTML would be as
    225 follows:
    226 
    227 @smallexample
    228 // php/index.html
    229 @verbatiminclude ../index.html
    230 @end smallexample
    231 
    232 When the server-side handler for @code{/donate.php} receives the form submission,
    233 it will return a HTML page that will take care of:
    234 
    235 @itemize
    236 @item showing a credit card paywall to the user if no wallet is found, and
    237 @item fetching a Taler proposal and passing it to the wallet if one is found
    238 @end itemize
    239 
    240 A minimalistic @code{donate.php} implementation is shown below (in PHP):
    241 
    242 @cindex pay handler
    243 @cindex 402
    244 @cindex X-Taler-Contract-Url
    245 @smallexample
    246 // php/donate.php
    247 @verbatiminclude ../donate.php
    248 @end smallexample
    249 
    250 Given this response, the Taler wallet will fetch the proposal from
    251 @url{/generate-order.php} and display it to the user.
    252 
    253 If the wallet is not present, the HTML body will be shown and the
    254 Taler headers and the 402 status code ought to be ignored by the
    255 browser.
    256 
    257 @section A helper function to generate the order
    258 
    259 We make distinction between @emph{three} different stages of what it
    260 informally called "contract".
    261 
    262 In a very first stage, we call it the @emph{order}: that occurs when
    263 the frontend generates the first JSON that misses some information
    264 that the backend is supposed to add.  When the backend completes the
    265 order and signs it, we have a @emph{proposal}.  The proposal is what
    266 the user is prompted with, and allows them to confirm the purchase.
    267 Once the user confirms the purchase, the wallet makes a signature over
    268 the proposal, turning it into a @emph{contract}.
    269 
    270 We first define a helper function @code{make_order} that will
    271 generate a complete Taler order as a nested PHP array.  The
    272 function takes only the order ID and the timestamp as arguments;
    273 all of the other details of the order are hardcoded in this simple
    274 example.
    275 
    276 The following code generate a order about donating 1 KUDOS to the
    277 'Taler charity program':
    278 
    279 @cindex contract
    280 @smallexample
    281 // php/order.php
    282 @verbatiminclude ../order.php
    283 @end smallexample
    284 
    285 
    286 @section Signing and returning the proposal
    287 
    288 The server-side handler for @code{/generate-order.php} has to call
    289 @code{make_order} and then POST the result to the backend at
    290 @code{/proposal}.  By POSTing the order to the backend we get a
    291 cryptographic signature over its contents.  The result is then
    292 returned to the wallet.
    293 
    294 A simple @code{/generate-order.php} handler may thus look like this:
    295 
    296 @cindex signature
    297 @cindex backend
    298 @cindex order
    299 @smallexample
    300 // php/generate-order.php
    301 @verbatiminclude ../generate-order.php
    302 @end smallexample
    303 
    304 @c FIXME: improve example to do this right?
    305 Note that in practice the frontend might want to generate a monotonically
    306 increasing series of order IDs to avoid a chance of collisions.
    307 Order IDs must be in the range of @math{[0:2^{51})}.
    308 
    309 @section Handling errors
    310 
    311 In the above example, the helper function @code{build_error} is
    312 used to generate an error response in the case that the backend
    313 somehow failed to respond properly to our request.
    314 
    315 The function @code{build_error} is shown below, it returns JSON data
    316 matching a particular format for reporting errors,
    317 see @code{http://api.taler.net/api-common.html#errordetail}:
    318 
    319 @smallexample
    320 @c FIXME, build_error() doesn't respect error-reporting format yet!
    321 // php/error.php
    322 @verbatiminclude ../error.php
    323 @end smallexample
    324 
    325 
    326 @node Initiating the payment process
    327 @section Initiating the payment process
    328 
    329 @cindex fulfillment URL
    330 After the browser has fetched the proposal, the user will be
    331 given the opportunity to affirm the payment.  Assuming the user
    332 affirms, the browser will navigate to the ``fulfillment_url'' that
    333 was specified in the proposal.
    334 
    335 The fulfillment page can be called by users that have already paid for
    336 the item, as well as by users that have not yet paid at all.  The
    337 fulfillment page must thus use the HTTP session state to detect if the
    338 payment has been performed already, and if not request payment from
    339 the wallet.
    340 
    341 For our example, the fulfillment URL will contain the order id of
    342 the donation, like in the following example:
    343 
    344 @smallexample
    345 https://shop.com/fulfillment.php?order_id=<ORDER_ID>
    346 @end smallexample
    347 
    348 The fulfillment handler at @code{/fulfillment.php} will use this information
    349 to check if the user has already paid, and if so confirm the donation.
    350 If the user has not yet paid, it will instead return another ``402 Payment
    351 Required'' header, requesting the wallet to pay:
    352 
    353 @smallexample
    354 // php/fulfillment.php
    355 @verbatiminclude ../fulfillment.php
    356 @end smallexample
    357 
    358 @cindex 402 payment required
    359 Here, this second 402 response contains the following Taler-specific
    360 headers:
    361 
    362 @table @code
    363 @item X-Taler-Contract-Url
    364 @cindex X-Taler-Contract-Url
    365 The URL that generated the proposal that led to this payment.
    366 The wallet may need to reconstruct the proposal.
    367 @item X-Taler-Contract-Query
    368 @cindex X-Taler-Contract-Query
    369 The way the wallet should lookup for replayable payments.
    370 NOTE that for each payment done, the wallet stores the coins it
    371 spent for it in an internal database. And each set of used coins
    372 is associated to the fulfillment page where they have been spent.
    373 So whenever an already known fulfillment page requests a payment,
    374 the wallet will pick those coins it spent on that fulfillment
    375 page and resend them (therefore @emph{replaying} the payment).
    376 In other words, new coins are used only on unknown fulfillment
    377 pages.
    378 This header is supposed to be removed in future versions of the
    379 wallet though, as it only works with the value @code{"fulfillment_url"}.
    380 @item X-Taler-Offer-Url
    381 @cindex X-Taler-Offer-Url
    382 In case that the wallet does not know about this payment already,
    383 i.e. because a user shared the URL with another user, this tells the
    384 wallet where to go to retrieve a fresh offer.
    385 @end table
    386 
    387 @section Receiving payments via Taler
    388 
    389 The final next step for the frontend is to accept the payment from the
    390 wallet.  For this, the frontend must implement a payment handler at
    391 the URI specified in the @code{pay_url} proposal field, as explained
    392 above.
    393 
    394 The role of the @code{/pay.php} handler is to receive the payment
    395 from the wallet and forward it to the backend.  If the backend
    396 reports that the payment was successful, the handler needs to update
    397 the session state with the browser to remember that the user paid.
    398 
    399 The following code implements this in PHP:
    400 
    401 @smallexample
    402 // php/pay.php
    403 @verbatiminclude ../pay.php
    404 @end smallexample
    405 
    406 Do not be confused by the @code{isset} test for the session state.  In
    407 our simple example, it will be set to ``false'' by the fulfillment URL
    408 which the browser actually always visits first.
    409 
    410 After the @code{pay.php} handler has affirmed that the payment was
    411 successful, the wallet will refresh the fulfillment page, this
    412 time receiving the message that the donation was successful.  If
    413 anything goes wrong, the wallet will handle the respective error.
    414 
    415 @node Back-office-integration
    416 @chapter Integration with the back office
    417 
    418 Taler ships the back-office feature as a stand-alone Web application.
    419 See how to run it, on its own documentaion: @url{https://docs.taler.net/backoffice/html/manual.html}.
    420 
    421 
    422 @node Advanced topics
    423 @chapter Advanced topics
    424 
    425 @menu
    426 * Detecting the presence of the Taler wallet::  Detecting the presence of the Taler wallet
    427 * The Taler proposal format::                   The Taler proposal format
    428 * Instances::                                   Instances
    429 * The fulfillment page::                        The fulfillment page
    430 * Normalized base URLs::                        Normalized base URLs
    431 @end menu
    432 
    433 @include ../../common/texi/wallet-detection.texi
    434 @include ../../common/texi/proposals.texi
    435 @include ../../common/texi/instances.texi
    436 @include ../../common/texi/fulfillment-page.texi
    437 @include ../../common/texi/normalized-base-url.texi
    438 
    439 
    440 @c ************ Reference chapter ***********
    441 @include ../../common/texi/api-reference.texi
    442 
    443 @c **********************************************************
    444 @c *******************  Appendices  *************************
    445 @c **********************************************************
    446 
    447 @node GNU-LGPL
    448 @unnumbered GNU-LGPL
    449 @cindex license
    450 @cindex LGPL
    451 @include ../../common/texi/lgpl.texi
    452 
    453 @node GNU-FDL
    454 @unnumbered GNU-FDL
    455 @cindex license
    456 @cindex GNU Free Documentation License
    457 @include ../../common/texi/fdl-1.3.texi
    458 
    459 @node Concept Index
    460 @unnumbered Concept Index
    461 
    462 @printindex cp
    463 
    464 @bye