3.1.5. Understanding fulfillment URLs#

Taler orders and contracts must contain either a fulfillment_url or a fulfillment_message, which are used by the wallet after the contract has been paid. This tutorial explains how to properly set these values.

3.1.5.1. Fulfillment message#

This field is simply a message that will be shown to the user by the Taler wallet after the user completed the purchase. It can be set to any kind of UTF-8 text and it supposed to be used as a friendly final message from the merchant at the end of the business transaction.

Nota

Whe wallets do learn the text before the purchase is made, so users could obtain the fulfillment message before the actual purchase. As a result, it should not contain any actual credentials or information that the user might be buying with the contract.

Fulfillment messages are used when the merchant does not have a fulfillment URL to redirect the user to.

3.1.5.2. Fulfillment URLs#

Contracts can contain a fulfillment_url instead of a fulfillment_message. The fulfillment_url must refer to a Web site (start with http:// or https://) and the user will be redirected there immediately after they completed the purchase and possibly later from the purchase details dialog in their wallet’s transaction history.

Fulfillment URLs serve a second purpose, which is that they are also used for repurchase detection. Thus, care must be taken to use fulfillment URLs correctly. We explain the two relevant scenarios and their motivation in the next two sections.

3.1.5.3. Repurchase detection#

Un possibile problema per i commercianti che vendono l’accesso agli articoli digitali è che un cliente potrebbe aver pagato per un articolo su un dispositivo, ma potrebbe poi volerlo leggere su un altro dispositivo, magari uno che non ha nemmeno un portafoglio Taler installato.

Naturally, at this point the customer would at first still be prompted to pay for the article again. If the customer then opens the taler:// link in the 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 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).

Il backend del commerciante aggiorna quindi l’ID di sessione dell’ordine esistente con l’ID di sessione corrente del browser. Quando viene controllato lo stato di pagamento del «nuovo» ordine non pagato (o già in long-polling), il backend rileva che per l”ID di sessione e l”URL di evasione del browser esiste un contratto già pagato. Quindi dice al browser di reindirizzare immediatamente all’URL di evasione dove è disponibile l’articolo già pagato.

It is thus crucial that merchants consistently use the same fulfillment URL for the same digital product where repurchase detection is desired.

Nota

Changing the session ID to a different device requires the involvement of the original wallet that made the payment, thus reasonably limiting the possibility of broadly sharing the digital purchases.

3.1.5.4. Allowing repeated purchases#

To ensure repurchase detection does not prevent customers from buying the same service or physical good a second time, merchants must make sure to not use the same fulfillment URL for different products or for physical products where customers may be expected to buy the article repeatedly.

A convenient way to create a unique fulfillment URL is to embed the order ID in the fulfillment URL. To enable using the order ID in a fulfillment URL even if the order_id field is not set by the merchant when POSTing a new order (and thus the actual order ID will be chosen by the merchant backend), you can use the placeholder text ${ORDER_ID} in the fulfillment_url when posting it to the merchant backend. The merchant backend will then immediately substitute ${ORDER_ID} in the URL with the actual order ID (before persisting the contract terms locally).