summaryrefslogtreecommitdiff
path: root/texinfo/taler-merchant-api-tutorial.texi
diff options
context:
space:
mode:
Diffstat (limited to 'texinfo/taler-merchant-api-tutorial.texi')
-rw-r--r--texinfo/taler-merchant-api-tutorial.texi182
1 files changed, 55 insertions, 127 deletions
diff --git a/texinfo/taler-merchant-api-tutorial.texi b/texinfo/taler-merchant-api-tutorial.texi
index 3f51b138..28b57ecc 100644
--- a/texinfo/taler-merchant-api-tutorial.texi
+++ b/texinfo/taler-merchant-api-tutorial.texi
@@ -3,29 +3,27 @@
@setfilename taler-merchant-api-tutorial.info
@documentencoding UTF-8
@ifinfo
-@*Generated by Sphinx 3.4.3.@*
+@*Generated by Sphinx 5.3.0.@*
@end ifinfo
@settitle Taler Merchant API Tutorial
@defindex ge
@paragraphindent 0
@exampleindent 4
@finalout
-@dircategory CATEGORY
+@dircategory Network applications
@direntry
-* MENU ENTRY: (taler-merchant-api-tutorial.info). DESCRIPTION
+* GNU Taler Merchant API: (taler-merchant-api-tutorial.info). Tutorial for using the merchant backend API
@end direntry
-@definfoenclose strong,`,'
-@definfoenclose emph,`,'
@c %**end of header
@copying
@quotation
-GNU Taler 0.8.0pre0, Apr 28, 2021
+GNU Taler 0.9.4, Apr 12, 2024
GNU Taler team
-Copyright @copyright{} 2014-2021 Taler Systems SA (GPLv3+ or GFDL 1.3+)
+Copyright @copyright{} 2014-2024 Taler Systems SA (GPLv3+ or GFDL 1.3+)
@end quotation
@end copying
@@ -49,17 +47,17 @@ Copyright @copyright{} 2014-2021 Taler Systems SA (GPLv3+ or GFDL 1.3+)
@c %**start of body
@anchor{taler-merchant-api-tutorial doc}@anchor{0}
@c This file is part of GNU TALER.
-@c Copyright (C) 2014-2020 Taler Systems SA
+@c Copyright (C) 2014-2023 Taler Systems SA
@c
@c TALER is free software; you can redistribute it and/or modify it under the
-@c terms of the GNU General Public License as published by the Free Software
+@c terms of the GNU Affero General Public License as published by the Free Software
@c Foundation; either version 2.1, or (at your option) any later version.
@c
@c TALER is distributed in the hope that it will be useful, but WITHOUT ANY
@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-@c A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
@c
-@c You should have received a copy of the GNU Lesser General Public License along with
+@c You should have received a copy of the GNU Affero General Public License along with
@c TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
@c
@c @author Marcello Stanisci
@@ -71,7 +69,6 @@ Copyright @copyright{} 2014-2021 Taler Systems SA (GPLv3+ or GFDL 1.3+)
* Merchant Payment Processing::
* Giving Refunds::
* Repurchase detection and fulfillment URLs::
-* Giving Customers Tips::
* Advanced topics::
* Index::
@@ -101,7 +98,7 @@ Advanced topics
@end menu
@node Introduction,Merchant Payment Processing,Top,Top
-@anchor{taler-merchant-api-tutorial gnu-taler-merchant-api-tutorial}@anchor{1}@anchor{taler-merchant-api-tutorial introduction}@anchor{2}@anchor{taler-merchant-api-tutorial merchant-api-tutorial}@anchor{3}
+@anchor{taler-merchant-api-tutorial id1}@anchor{1}@anchor{taler-merchant-api-tutorial introduction}@anchor{2}@anchor{taler-merchant-api-tutorial merchant-api-tutorial}@anchor{3}
@chapter Introduction
@@ -134,7 +131,7 @@ regulation (such as GDPR).
This tutorial addresses how to process payments using the GNU Taler merchant
-Backend. The audience for this tutorial are @emph{developers} of merchants (such
+Backend. The audience for this tutorial are `developers' of merchants (such
as Web shops) that are working on integrating GNU Taler with the
customer-facing Frontend and the staff-facing Backoffice.
@@ -160,11 +157,6 @@ that accepts donations for software projects and gives donation
receipts.
@item
-The
-survey@footnote{https://git.taler.net/taler-merchant-demos.git/tree/talermerchantdemos/survey}
-that gives users who answer a question a small reward.
-
-@item
The WooCommerce plugin@footnote{https://git.taler.net/gnu-taler-payment-for-woocommerce.git/}
which is a comprehensive integration into a Web shop including the refund business
process.
@@ -237,12 +229,12 @@ configuration. See taler-merchant-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.
+@code{Bearer secret-token:sandbox} for the public sandbox backend.
@example
>>> import requests
->>> requests.get("https://backend.demo.taler.net",
-... headers=@{"Authorization": "ApiKey sandbox"@})
+>>> requests.get("https://backend.demo.taler.net/private/orders",
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
<Response [200]>
@end example
@@ -261,10 +253,10 @@ imaginary currency. Coins denominated in @code{KUDOS} can be withdrawn from
@section Merchant Instances
-The same Taler merchant backend server can be used by multiple separate
+A single Taler merchant backend server can be used by multiple
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
+business entities is assigned a `merchant instance' which is identified by
+an alphanumeric `instance id'. If the instance is omitted, the instance
id @code{default} is assumed.
The following merchant instances are configured on
@@ -297,7 +289,7 @@ All endpoints for instances offer the same API. Thus, which instance
to be used is simply included in the base URL of the merchant backend.
@node Merchant Payment Processing,Giving Refunds,Introduction,Top
-@anchor{taler-merchant-api-tutorial id1}@anchor{9}@anchor{taler-merchant-api-tutorial merchant-payment-processing}@anchor{a}
+@anchor{taler-merchant-api-tutorial id2}@anchor{9}@anchor{taler-merchant-api-tutorial merchant-payment-processing}@anchor{a}
@chapter Merchant Payment Processing
@@ -314,7 +306,7 @@ to be used is simply included in the base URL of the merchant backend.
@section Creating an Order for a Payment
-Payments in Taler revolve around an @emph{order}, which is a machine-readable
+Payments in Taler revolve around an `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.
@@ -362,10 +354,10 @@ A minimal Python snippet for creating an order would look like this:
>>> body = dict(order=dict(amount="KUDOS:10",
... summary="Donation",
... fulfillment_url="https://example.com/thanks.html"),
-... create_token=false)
->>> response = requests.post("https://backend.demo.taler.net/private/order",
+... create_token=False)
+>>> response = requests.post("https://backend.demo.taler.net/private/orders",
... json=body,
-... headers=@{"Authorization": "ApiKey sandbox"@})
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
<Response [200]>
@end example
@@ -373,7 +365,7 @@ A minimal Python snippet for creating an order would look like this:
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'.
@geindex contract terms
@@ -386,19 +378,23 @@ given below to include the claim token.
@end quotation
@end cartouche
-After successfully @code{POST}ing to @code{/private/orders}, an @code{order_id} will be
-returned. Together with the merchant @code{instance}, the order id uniquely
-identifies the order within a merchant backend. Using the order ID, you
-can trivially construct the respective @code{taler://pay/} URI that must
-be provided to the wallet. Let @code{example.com} be the domain name where
-the public endpoints of the instance are reachable. The Taler pay URI is
-then simply @code{taler://pay/example.com/$ORDER_ID/} where @code{$ORDER_ID}
-must be replaced with the ID of the order that was returned.
+After successfully @code{POST}ing to @code{/private/orders}, a JSON with just an
+@code{order_id} field with a string representing the order ID will be returned.
+If you also get a claim token, please double-check that you used the request
+as described above.
+
+Together with the merchant @code{instance}, the order id uniquely identifies the
+order within a merchant backend. Using the order ID, you can trivially
+construct the respective @code{taler://pay/} URI that must be provided to the
+wallet. Let @code{example.com} be the domain name where the public endpoints of
+the instance are reachable. The Taler pay URI is then simply
+@code{taler://pay/example.com/$ORDER_ID/} where @code{$ORDER_ID} must be replaced
+with the ID of the order that was returned.
You can put the @code{taler://} URI as the target of a link to open the Taler
wallet via the @code{taler://} schema, or put it into a QR code. However, for a
Web shop, the easiest way is to simply redirect the browser to
-@code{https://example.com/orders/$ORDER_ID/}. That page will then trigger the
+@code{https://example.com/orders/$ORDER_ID}. That page will then trigger the
Taler wallet. Here the backend generates the right logic to trigger the
wallet, supporting the various types of Taler wallets in existence. Instead
of constructing the above URL by hand, it is best to obtain it by checking for
@@ -410,11 +406,11 @@ the payment status as described in the next section.
Given the order ID, the status of a payment can be checked with the
-@code{/private/orders/$ORDER_ID/} endpoint. If the payment is yet to be completed
+@code{/private/orders/$ORDER_ID} endpoint. If the payment is yet to be completed
by the customer, @code{/private/orders/$ORDER_ID} will give the frontend a URL
(under the name @code{payment_redirect_url}) that will trigger the customer’s
wallet to execute the payment. This is basically the
-@code{https://example.com/orders/$ORDER_ID/} URL we discussed above.
+@code{https://example.com/orders/$ORDER_ID} URL we discussed above.
Note that the best way to obtain the @code{payment_redirect_url} is to check the
status of the payment, even if you know that the user did not pay yet. There
@@ -424,7 +420,7 @@ backend to do it is the safest method.
@example
>>> import requests
>>> r = requests.get("https://backend.demo.taler.net/private/orders/" + order_id,
-... headers=@{"Authorization": "ApiKey sandbox"@})
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
>>> print(r.json())
@end example
@@ -453,7 +449,7 @@ the merchant’s obligations under the contract.
@cartouche
@quotation Note
You do not need to keep querying to notice changes
-to the order's transaction status. The endpoints
+to the order’s transaction status. The endpoints
support long polling, simply specify a @code{timeout_ms}
query parameter with how long you want to wait at most
for the order status to change to @code{paid}.
@@ -463,7 +459,7 @@ for the order status to change to @code{paid}.
@geindex refunds
@node Giving Refunds,Repurchase detection and fulfillment URLs,Merchant Payment Processing,Top
-@anchor{taler-merchant-api-tutorial id2}@anchor{f}
+@anchor{taler-merchant-api-tutorial id3}@anchor{f}
@chapter Giving Refunds
@@ -488,7 +484,7 @@ The refund request JSON object has only two fields:
@code{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.
+refunded, `not' an increase in the refund.
@item
@code{reason}: Human-readable justification for the refund. The reason is
@@ -508,14 +504,14 @@ This code snipped illustrates giving a refund:
... reason="Customer did not like the product")
>>> requests.post("https://backend.demo.taler.net/private/orders/"
... + order_id + "/refund", json=refund_req,
-... headers=@{"Authorization": "ApiKey sandbox"@})
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
<Response [200]>
@end example
@cartouche
@quotation Note
After granting a refund, the public
-@code{https://example.com/orders/$ORDER_ID/} endpoint will
+@code{https://example.com/orders/$ORDER_ID} endpoint will
change its wallet interaction from requesting payment to
offering a refund. Thus, frontends may again redirect
browsers to this endpoint. However, to do so, a
@@ -529,7 +525,7 @@ under the @code{h_contract} field.
@geindex repurchase
-@node Repurchase detection and fulfillment URLs,Giving Customers Tips,Giving Refunds,Top
+@node Repurchase detection and fulfillment URLs,Advanced topics,Giving Refunds,Top
@anchor{taler-merchant-api-tutorial repurchase}@anchor{10}@anchor{taler-merchant-api-tutorial repurchase-detection-and-fulfillment-urls}@anchor{11}
@chapter Repurchase detection and fulfillment URLs
@@ -544,15 +540,15 @@ for the article again. If the customer then opens the @code{taler://} link in th
wallet that did previously pay for the article (for example by scanning the QR
code on the desktop with the Android App), the wallet will claim the contract,
detect that the fulfillment URL is identical to one that it already has made a
-payment for in the past, and initiate @strong{repurchase redirection}: Here, the
+payment for in the past, and initiate `repurchase redirection': Here, the
wallet will contact the merchant and replay the previous payment, except this
time using the (current) session ID of the browser (it learns the session ID
from the QR code).
The merchant backend then updates the session ID of the existing order to
the current session ID of the browser. When the payment status for the
-"new" unpaid order is checked (or already in long-polling), the backend
-detects that for the browser's @emph{session ID} and @emph{fulfillment URL} there is an
+“new” unpaid order is checked (or already in long-polling), the backend
+detects that for the browser’s `session ID' and `fulfillment URL' there is an
existing paid contract. It then tells the browser to immediately redirect to
the fulfillment URL where the already paid article is available.
@@ -565,81 +561,13 @@ the same digital product where repurchase detection is desired.
Note that changing the session ID to a different device requires the
involvement of the wallet that made the payment, thus reasonably limiting the
possibility of broadly sharing the digital purchases. Repurchase detection is
-also @emph{only} done for HTTP(S) fulfillment URLs. In particular, this means
+also `only' done for HTTP(S) fulfillment URLs. In particular, this means
fulfillment URIs like @code{taler://fulfillment-success/$MESSAGE} are not
considered to identify a resource you can pay for and thus do not have to be
unique.
-@anchor{taler-merchant-api-tutorial giving-customers-tips}@anchor{12}
-@geindex tips
-
-@node Giving Customers Tips,Advanced topics,Repurchase detection and fulfillment URLs,Top
-@anchor{taler-merchant-api-tutorial id4}@anchor{13}
-@chapter Giving Customers Tips
-
-GNU Taler allows Web sites to grant small amounts directly to the
-visitor. The idea is that some sites may want incentivize actions such
-as filling out a survey or trying a new feature. It is important to note
-that tips are not enforceable for the visitor, as there is no contract.
-It is simply a voluntary gesture of appreciation of the site to its
-visitor. However, once a tip has been granted, the visitor obtains full
-control over the funds provided by the site.
-
-The “merchant” backend of the site must be properly configured for
-tipping, and sufficient funds must be made available for tipping See
-Taler Merchant Operating Manual.
-
-To check if tipping is configured properly and if there are sufficient
-funds available for tipping, query the @code{/tip-query} endpoint:
-
-@example
->>> import requests
->>> requests.get("https://backend.demo.taler.net/tip-query?instance=default",
-... headers=@{"Authorization": "ApiKey sandbox"@})
-<Response [200]>
-@end example
-@anchor{taler-merchant-api-tutorial authorize-tip}@anchor{14}
-To authorize a tip, @code{POST} to @code{/tip-authorize}. The following fields
-are recognized in the JSON request object:
-
-
-@itemize -
-
-@item
-@code{amount}: Amount that should be given to the visitor as a tip.
-
-@item
-@code{instance}: Merchant instance that grants the tip (each instance may
-have its own independent tipping funds configured).
-
-@item
-@code{justification}: Description of why the tip was granted. Human-readable
-text not exposed to the customer, but used by the Back Office.
-
-@item
-@code{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.
-@anchor{taler-merchant-api-tutorial pick-up-tip}@anchor{15}
-This code snipped illustrates giving a tip:
-
-@example
->>> import requests
->>> tip_req = dict(amount="KUDOS:0.5",
-... instance="default",
-... justification="User filled out survey",
-... next_url="https://merchant.com/thanks.html")
->>> requests.post("https://backend.demo.taler.net/tip-authorize", json=tip_req,
-... headers=@{"Authorization": "ApiKey sandbox"@})
-<Response [200]>
-@end example
-
-@node Advanced topics,Index,Giving Customers Tips,Top
-@anchor{taler-merchant-api-tutorial advanced-topics}@anchor{16}@anchor{taler-merchant-api-tutorial id6}@anchor{17}
+@node Advanced topics,Index,Repurchase detection and fulfillment URLs,Top
+@anchor{taler-merchant-api-tutorial advanced-topics}@anchor{12}@anchor{taler-merchant-api-tutorial id4}@anchor{13}
@chapter Advanced topics
@@ -651,7 +579,7 @@ This code snipped illustrates giving a tip:
@end menu
@node Session-Bound Payments,Product Identification,,Advanced topics
-@anchor{taler-merchant-api-tutorial session-002dbound-payments}@anchor{18}@anchor{taler-merchant-api-tutorial session-bound-payments}@anchor{19}
+@anchor{taler-merchant-api-tutorial session-002dbound-payments}@anchor{14}@anchor{taler-merchant-api-tutorial session-bound-payments}@anchor{15}
@section Session-Bound Payments
@@ -688,7 +616,7 @@ 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 id8}@anchor{1a}@anchor{taler-merchant-api-tutorial product-identification}@anchor{1b}
+@anchor{taler-merchant-api-tutorial id5}@anchor{16}@anchor{taler-merchant-api-tutorial product-identification}@anchor{17}
@section Product Identification
@@ -709,7 +637,7 @@ 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 id9}@anchor{1c}@anchor{taler-merchant-api-tutorial the-taler-order-format}@anchor{1d}
+@anchor{taler-merchant-api-tutorial id6}@anchor{18}@anchor{taler-merchant-api-tutorial the-taler-order-format}@anchor{19}
@section The Taler Order Format
@@ -1020,8 +948,8 @@ render fields that they do not understand as a key-value list.
@printindex ge
-@anchor{taler-merchant-api-tutorial The-Taler-Order-Format}@w{ }
@anchor{c}@w{ }
+@anchor{taler-merchant-api-tutorial The-Taler-Order-Format}@w{ }
@c %**end of body
@bye