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.texi156
1 files changed, 78 insertions, 78 deletions
diff --git a/texinfo/taler-merchant-api-tutorial.texi b/texinfo/taler-merchant-api-tutorial.texi
index 558313fe..a06c4e93 100644
--- a/texinfo/taler-merchant-api-tutorial.texi
+++ b/texinfo/taler-merchant-api-tutorial.texi
@@ -3,7 +3,7 @@
@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
@@ -15,13 +15,11 @@
* MENU ENTRY: (taler-merchant-api-tutorial.info). DESCRIPTION
@end direntry
-@definfoenclose strong,`,'
-@definfoenclose emph,`,'
@c %**end of header
@copying
@quotation
-GNU Taler 0.9.0, Nov 03, 2022
+GNU Taler 0.9.0, Sep 24, 2023
GNU Taler team
@@ -49,7 +47,7 @@ Copyright @copyright{} 2014-2022 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 Affero General Public License as published by the Free Software
@@ -71,7 +69,7 @@ Copyright @copyright{} 2014-2022 Taler Systems SA (GPLv3+ or GFDL 1.3+)
* Merchant Payment Processing::
* Giving Refunds::
* Repurchase detection and fulfillment URLs::
-* Giving Customers Tips::
+* Giving Customers Rewards::
* Advanced topics::
* Index::
@@ -134,7 +132,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.
@@ -237,12 +235,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": "secret-token:secret"@})
+>>> requests.get("https://backend.demo.taler.net/private/orders",
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
<Response [200]>
@end example
@@ -261,10 +259,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
@@ -314,7 +312,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 +360,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)
+... create_token=False)
>>> response = requests.post("https://backend.demo.taler.net/private/orders",
... json=body,
-... headers=@{"Authorization": "secret-token:secret"@})
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
<Response [200]>
@end example
@@ -373,7 +371,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 +384,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 +412,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 +426,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": "secret-token:secret"@})
+... headers=@{"Authorization": "Bearer secret-token:sandbox"@})
>>> print(r.json())
@end example
@@ -453,7 +455,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}.
@@ -488,7 +490,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 +510,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": "secret-token:secret"@})
+... 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 +531,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,Giving Customers Rewards,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 +546,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 +567,79 @@ 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
+@anchor{taler-merchant-api-tutorial giving-customers-rewards}@anchor{12}
+@geindex rewards
-@node Giving Customers Tips,Advanced topics,Repurchase detection and fulfillment URLs,Top
-@anchor{taler-merchant-api-tutorial id4}@anchor{13}
-@chapter Giving Customers Tips
+@node Giving Customers Rewards,Advanced topics,Repurchase detection and fulfillment URLs,Top
+@anchor{taler-merchant-api-tutorial id3}@anchor{13}
+@chapter Giving Customers Rewards
-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.
+GNU Taler allows Web sites to grant digital cash directly to a 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 receiving rewards is
+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
+reward 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.
+The merchant backend of the site must be properly configured for rewards, and
+sufficient funds must be made available for rewards. See the Taler User
+Guide for details.
-To check if tipping is configured properly and if there are sufficient
-funds available for tipping, query the @code{/tip-query} endpoint:
+To check if rewards are configured properly and if there are sufficient
+funds available for granting rewards, query the @code{/private/reserves} endpoint:
@example
>>> import requests
->>> requests.get("https://backend.demo.taler.net/tip-query?instance=default",
-... headers=@{"Authorization": "secret-token:secret"@})
+>>> requests.get("https://backend.demo.taler.net/private/reserves",
+... headers=@{"Authorization": "Bearer secret-token: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
+
+Check that a reserve exists where the @code{merchant_initial_amount} is below the
+@code{committed_amount} and that the reserve is @code{active}.
+@anchor{taler-merchant-api-tutorial authorize-reward}@anchor{14}
+To authorize a reward, @code{POST} to @code{/private/rewards}. 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).
+@code{amount}: Amount that should be given to the visitor as a reward.
@item
-@code{justification}: Description of why the tip was granted. Human-readable
+@code{justification}: Description of why the reward 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.
+the wallet, once the reward has been processed.
@end itemize
-The response from the backend contains a @code{tip_redirect_url}. The
+The response from the backend contains a @code{taler_reward_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:
+up the reward.
+@anchor{taler-merchant-api-tutorial pick-up-reward}@anchor{15}
+This code snipped illustrates giving a reward:
@example
>>> import requests
->>> tip_req = dict(amount="KUDOS:0.5",
-... instance="default",
+>>> reward_req = dict(amount="KUDOS:0.5",
... 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": "secret-token:secret"@})
+>>> requests.post("https://backend.demo.taler.net/private/rewards", json=reward_req,
+... headers=@{"Authorization": "Bearer secret-token: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,Giving Customers Rewards,Top
+@anchor{taler-merchant-api-tutorial advanced-topics}@anchor{16}@anchor{taler-merchant-api-tutorial id4}@anchor{17}
@chapter Advanced topics
@@ -688,7 +688,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{1a}@anchor{taler-merchant-api-tutorial product-identification}@anchor{1b}
@section Product Identification
@@ -709,7 +709,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{1c}@anchor{taler-merchant-api-tutorial the-taler-order-format}@anchor{1d}
@section The Taler Order Format