summaryrefslogtreecommitdiff
path: root/php/doc/tutorial.texi
blob: d085cda6b3226b9c0ef17807a3ac42e22b084787 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename tutorial.info
@include version.texi
@settitle The GNU Taler tutorial for 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 INRIA

@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 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})
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@summarycontents
@contents

@ifnottex
@node Top
@top The GNU Taler tutorial for Web shops
@insertcopying
@end ifnottex

@menu
* Introduction::            Whom this tutorial is addressed to
* Hello-world::             How to set up a donation page
* Back-office-integration:: How to integrate with the back office
* Advanced topics::         Detailed solutions to specific issues


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 contract 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/}.

@c Add section giving an overview of what we will do in the tutorial!


@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}


Basically, 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 Hello-world
@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
contract offering him the opportunity to make a fixed donation,
for example to donate 1 KUDOS to the charity operating the shop.

Please note the 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!

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 we will need 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 backend 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 contract 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 contract from
@url{/generate-contract.php} and display it to the user.


@section A helper function to generate the proposed contract

We first define a helper function @code{make_contract} that will
generate a complete Taler contract as a nested PHP array.  The
function takes only the transaction ID and the timestamp as arguments,
all of the other details of the contract are hardcoded in this simple
example.

The following code generate a contract proposal about donating 1 KUDOS
to the 'Taler charity program':

@cindex contract
@smallexample
// php/contract.php
@verbatiminclude ../contract.php
@end smallexample


@section Signing and returning the proposal

The server-side handler for @code{/generate-contract.php} has to call
@code{make_contract} and then POST the result to the backend at
@code{/contract}.  By POSTing the proposed contract to the backend we get a
cryptographic signature over its contents.  The result is then
returned to the wallet.

A simple @code{/generate-contract.php} handler may thus look like this:

@cindex signature
@cindex backend
@cindex contract
@smallexample
// php/generate-contract.php
@verbatiminclude ../generate-contract.php
@end smallexample

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.

@c FIXME: improve example to do this right?
Note that in practice the frontend might want to generate a monotonically
increasing series of transaction IDs to avoid a chance of collisions.
Transaction 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 contract 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 contract.

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, we include in the URI of the fulfillment page the information
which is needed to allow the page to determine which contract the user is
trying to access.
Thus, the fulfillment URL for our example looks like the following:@*

@smallexample
https://shop.com/fulfillment.php? \
transaction_id=<TRANSACTION_ID>&timestamp=<CONTRACTTIMESTAMP>
@end smallexample

The fulfillment handler will 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-Hash
@cindex X-Taler-Contract-Hash
The wallet needs to know which contract we are asking it to pay for.
To reduce bandwidth consumption, we do not transmit the full contract
again, but just the hash of it.
@item X-Taler-Pay-Url
@cindex X-Taler-Pay-Url
This URL specifies where we expect the wallet to send the payment.
@item X-Taler-Offer-Url
@cindex X-Taler-Offer-Url
In case that the wallet does not know about this contract already,
i.e. because a user shared the URL with another user, this tells the
wallet where to go to retrieve the original offer.
@c FIXME: do implement offer-URL properly for the tutorial!
@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 for as the @code{X-Taler-Pay-Url} in the headers
as explained above.

The role of the @code{/pay} 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

This chapter shows how to implement the back office Web interface.

We will use the term @emph{transaction} to refer to the business
transaction that a merchant has with a customer (and the related
communication with the Taler exchange for payment), and the term
@emph{wire transfer} to refer to the exchange settling its accounts
with the merchant.

Given that Taler deals with microtransactions, not every customer
payment processed with Taler will necessarily correspond to a wire
transfer.  The Taler exchange may aggregate multiple payments from
transactions into one larger wire transfer.  The @var{refund_deadline}
and the @var{pay_deadline} values in the contract specify the
timeframes within which the exchange is permitted to perform such
aggregations.

In this chapter, we will see how a merchant can obtain the
mapping from transactions to wire transfers and vice versa.
Additionally, we will describe how to obtain a list of all
transactions known to the backend.

@section Entry page

Given this charge, the back office's main tasks are:

@itemize
@item
Allow the back office operator to specify a transaction ID, and
display the corresponding wire transfer identifiers
@item
Allow the back office operator to specify a wire transfer ID, and
display all of the corresponding transaction IDs
@item
Allow the back office operator to obtain a list of all transactions.
@end itemize

We implement these with a simple HTML form. For simplicity, we have
one single page for gathering input data for both tracking directions:

@smallexample
// php/backoffice.html
@verbatiminclude ../backoffice.html
@end smallexample

The imported script @code{history.js} is responsible for dynamically
get the list of known transactions.  See below.

@section Tracking a transaction

The @code{track-transaction.php} script is now responsible for taking
the Taler transaction ID given by the user in the @code{tid} field,
and using it to issue a @code{/track/transaction} request to the
backend, see
@url{http://api.taler.net/api-merchant.html#get--track-transaction}.
Note that the backend may then request this information from the
exchange, or retrieve it from its own cache if it has already obtained
it.  The backend will also check signatures from the exchange, persist
the information obtained, and complain if the exchange ever changes
its facts in an inconsistent manner.

@smallexample
// php/track-transaction.php
@verbatiminclude ../track-transaction.php
@end smallexample

If the backend returned an HTTP status code @code{202} (Accepted),
this means that the exchange simply did yet not perform the wire
transfer. This is usually the case before the @var{refund_deadline} as
the exchange is waiting for additional opportunities to aggregate
transactions.  In this case, we tell the user when to retry this
operation later.

In the @code{foreach} loop, we construct the list of all the
wire transfers which paid back transaction @code{tid}.  For
simplicity, the list will report only two values: the wire transfer
identifier and the date when the transfer occurred. Nonetheless,
the data returned by the backend contains more information that
can be shown to the user.

@section Tracking a wire transfer

To track a wire transfer, we first check if the user submitted all the
required parameters, and then we forward the request to the backend.
Again, the backend may request missing information from the exchange,
verify signatures, persist the result and complain if there are
inconsistencies.

In the case that the backend detects inconsistencies, an HTTP status
code of @code{402} is returned.  In this case, we report this
situation to the user, who should now report this situation to the
exchange's auditors as the exchange is misbehaving.

In the usual case where everything went fine, we first output the
amount that was supposed to have been transfered under the given
@code{wtid}, and when it was performed (according to the exchange).
Finally, in the @code{foreach} loop, we construct the list of the
transaction IDs paid by the wire transfer:

@smallexample
@verbatiminclude ../track-transfer.php
@end smallexample


@section Listing all transactions

In order to track transactions, transaction IDs are needed as input.
To that purpose, the frontend needs to make a HTTP GET request to
@code{/history?date=<TIMESTAMP>}, which is offered by the backend.
The returned data lists all the transactions from @emph{<TIMESTAMP>}
to now.

Our example frontend, implements this feature by orchestrating two
parts:

@itemize
@item The @code{history.php?days=<DAYSAGO>} script, whose @code{days}
      parameter indicates how old the oldest returned transaction should
      be in terms of days.  The script will then translate @emph{<DAYSAGO>}
      in a timestamp, and issue the call to backend's
      @code{/history?date=<TIMESTAMP>}.  The data it receives from the
      backend is finally returned in JSON format to the caller.

@item A JavaScript function, imported within @code{backoffice.html},
      that issues the HTTP GET to @code{/history.php?days=<DAYSAGO>}
      and modifies the current page by adding a table showing the result.
@end itemize

See below both parts:

@smallexample
// ../history.php
@verbatiminclude ../history.php
@end smallexample

@smallexample
// ../history.js
@verbatiminclude ../history.js
@end smallexample

@node Advanced topics
@chapter Advanced topics

@menu
* Presence detection::          Reacting to the presence of a Taler wallet
* Taler contracts::             Building Taler contracts
* Inline contracts::            Snding contracts with the HTTP header
* Payments using JavaScript::   Triggering payments using JavaScript
* The Fulfillment page::        The rationale behind the fulfillment page design
@end menu


@node Presence detection
@section Reacting to the presence of a Taler wallet
@cindex wallet

Taler offers the way to the frontend developer to detect whether
a user has the wallet installed in their browser, and take actions
accordingly.

@subsection The no-JavaScript way
The follwing example shows all that is needed to perform the detection
without using JavaScript:

@smallexample
<!DOCTYPE html>
<html lang="en" 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 smallexample

The @code{taler-fallback.css} is part of the Taler's @emph{web-common} repository,
available at @code{https://git.taler.net/web-common.git}.  Please adjust the @code{href}
attribute in order to make it work with your Web site.

The detection works by @code{taler-fallback.css} hiding any tag from the
@code{taler-installed-show} class, in case no wallet is installed.  If otherwise
the wallet is installed, the wallet takes action by hiding any tag from
@code{taler-installed-hide} and overriding @code{taler-fallback.css} logic
by showing any tag from the @code{taler-installed-show} class.

@subsection The JavaScript way

In this case, the @code{taler-wallet-lib} helps the frontend, by providing
the way to register two callbacks: one to be executed if a wallet is present,
the other if it is not.  See the example below:

@smallexample
<html lang="en">
  <head>
    <script src="/web-common/taler-wallet-lib.js" type="application/javascript">
    </script>
  </head>
  <body>
    <div id="content">
    </div>
    <script type="application/javascript">

      content = document.getElementById("content");
      p = document.createElement("p");

      function walletInstalled(){
        p.textContent = "Wallet installed!";
        content.appendChild(p);
      }
      function walletNotInstalled(){
        p.textContent = "Wallet not found.";
        content.appendChild(p);
      }
      taler.onPresent(wallerInstalled);
      taler.onAbsent(wallerNotInstalled);
    </script>
  </body>
</html>
@end smallexample

@code{taler-wallet-lib.js} exports the @code{taler} object that
exposes the @code{onPresent} and the @code{onAbsent} functions needed
to register the frontend's callbacks.  Thus the function @code{walletInstalled}
will be executed whenever a wallet is installed, and @code{walletNotInstalled}
if not.  Note that since now we can use JavaScript we can register
callbacks that do more than just showing and hiding elements.


@node Taler contracts
@section Building Taler contracts
@cindex contract

A Taler contract can specify many details about the transaction.
This section describes each of the fields in depth.

@table @var
@item amount
@cindex amount
Specifies the total amount to be paid to the merchant by the customer.
The amount is broken up into a @var{value}, a @var{fraction}
(100.000.000 @var{fraction} units correspond to one @var{value}) and
the @var{currency}.  For example, @code{EUR 1.50} would be represented
as the tuple @code{value = 1, fraction = 50000000, currency = "EUR"}.

@item max_fee
@cindex fees
@cindex 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 @var{amount}.

@item fulfillment_url
@cindex 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 transaction_id
@cindex transaction ID
Numeric transaction ID, must be in the range @math{[0,2^{51})}.
Used by the merchant to uniquely identify the transaction.

@item summary
@cindex 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.
@c FIXME: describe time format in detail here

@item pay_deadline
@cindex 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 @var{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
@cindex 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 @var{pay_deadline}.

@item products
@cindex product description
Array of products that are being sold to the customer.  Each
entry contains a tuple with the following values:

@table @var
@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 @var{quantity} units of this product shipped to the
given @var{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,2^{51})}.
@item taxes
Map of applicable taxes to be paid by the merchant.  The label is the
name of the tax, i.e. @var{VAT}, @var{sales tax} or @var{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
@var{delivery_location}.
@item delivery_location
This should give a label in the @var{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 @var{product_id} or @var{price} may not be
specified in the contract.  Similarly, for virtual products delivered
directly via the fulfillment URI, there is no delivery location.

@item repurchase_correlation_id
@cindex repurchase correlation ID
FIXME: explain!!!

@item merchant
@table @var
@item address
This should give a label in the @var{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 @var{locations} map, specifying
the jurisdiction under which this contract is to be arbitrated.
@end table

@item locations
@cindex 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 @var
@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.
@item name
@end table
Note that locations are not required to specify all of these fields,
and it 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


@node Inline contracts
@section Inlining contracts in HTTP headers
@cindex optimization
@cindex contract

In the example in @ref{Prompting for payment}, we told the wallet the URL
from where it should fetch the contract.  Instead of specifying the contract
via an URL, it is also possible to inline short contracts directly.

That may be accomplished by the frontend including the @code{X-Taler-Contract}
HTTP header, whenever the requested page is meant to trigger a payment.
The example shown below may be an alternative version of @code{/donate.php},
which implements inline contracts.

@smallexample
// ../inline.php
@verbatiminclude ../inline.php
@end smallexample

The wallet will then look for the @code{X-Taler-Contract} header, and fetch the
inlined contract if this header is found.  Please note that this feature is not
yet implemented.

@node Payments using JavaScript
@section Triggering payments using JavaScript
@cindex JavaScript
@cindex payment

In the example in section @ref{Initiating the payment process},
we used a GET request to trigger the payment.  This section describes how we
could have instead performed the interaction with the wallet directly from the
button via JavaScript.

The function @code{executePayment} exported by @code{taler-wallet-lib.js} will basically
hand its three parameters to the wallet which implements the following semantics:@*
check in the internal DB if @code{$response['H_contract']} has an entry, and:
@itemize
@item if that is the case, then the user accepted the contract previously and the wallet
sends a deposit permission @footnote{Roughly speaking, a deposit permission is a JSON
containing the coins to pay for a contract. Its full specification is available at:
@url{https://api.taler.net/api-merchant.html#depositpermission}} to @code{/frontend-pay}.
If this operation succeeds, then visit again the fulfillment URL, and finally enjoy
the product.
@item if not, redirect the browser to @code{/donate.php} (which will then reinitiate the
whole contract negotiation). This happens when the user visits a shared fulfillment URL.
The idea is to let that user buy the same products as the user who shared the fulfillment
URL. Nonetheless, the shop is not forced to follow this semantics when provides the third
parameter to @code{executePayment}.
@end itemize


@node The Fulfillment page
@section Design considerations for the fulfillment page
@cindex fulfillment page

The fulfillment page mechanism is designed to provide the following two properties:

@enumerate
@item Taler payments @emph{can} be implemented in DB-less frontends.

@item Taler payments are replayable, meaning that each purchase is associated with
a URL (the fulfillment URL) that shows the product each time it gets visited (and
of course, only the first time takes the user's money).
@end enumerate

In order to implement property (1), the frontend needs a way to recall
what a contract is about (e.g. which product, which price, the
timestamp, etc.) before proceeding with the actual payment and
eventually deliver the final product.  That is achieved by
@emph{reconstructing} the contract using the fulfillment page's URL
parameters@footnote{the fulfillment URL equipped with all the
parameters is included in the contract}.

In order to implement property (2), the frontend will firstly check
the state to see if the product claimed among the fulfillment URL
parameter has been paid; if so, the product is given to the
customer. Otherwise, the frontend sets the payment as "pending" in the
state and @emph{executes} it in the wallet. The payment execution is
performed by returning JavaScript code from @code{taler-wallet-lib.js}
that triggers the wallet to send the payment to the pay page.  Once
the pay page receives the payment, it sets the state for the payment
as "payed".



@c **********************************************************
@c *******************  Appendices  *************************
@c **********************************************************

@node GNU-LGPL
@unnumbered GNU-LGPL
@cindex license
@cindex LGPL
@include lgpl.texi

@node GNU-FDL
@unnumbered GNU-FDL
@cindex license
@cindex GNU Free Documentation License
@include fdl-1.3.texi

@node Concept Index
@unnumbered Concept Index

@printindex cp

@bye