1.2.2. Anleitung für Taler Merchant API#

1.2.2.1. Einführung#

1.2.2.1.1. Über GNU Taler#

GNU Taler ist ein offenes Protokoll für ein elektronisches Zahlungssystem mit einer freien Software-Referenzimplementierung. GNU Taler bietet eine sichere, schnelle und einfache Zahlungsabwicklung unter Verwendung gut verstandener kryptographischer Techniken. GNU Taler ermöglicht es den Kunden, anonym zu bleiben, und stellt gleichzeitig sicher, dass die Händler von den Regierungen zur Rechenschaft gezogen werden können. Daher ist GNU Taler mit Anti-Geldwäsche- (AML) und Know-Your-Customer- (KYC) Vorschriften sowie mit Datenschutzbestimmungen (wie GDPR) kompatibel.

1.2.2.1.2. Über dieses Lernprogramm#

Dieses Tutorial behandelt die Verarbeitung von Zahlungen mit dem GNU Taler Händler-Backend. Die Zielgruppe für dieses Tutorial sind Entwickler von Händlern (wie z.B. Webshops), die daran arbeiten, GNU Taler mit dem kundenorientierten Frontend und dem mitarbeiterorientierten Backoffice zu integrieren.

In diesem Kapitel werden einige grundlegende Konzepte erläutert. Im zweiten Kapitel werden Sie lernen, wie man grundlegende Zahlungen durchführt.

Diese Version des Tutorials enthält Beispiele für Python3. Sie verwendet die requests-Bibliothek für HTTP-Anfragen. Versionen für andere Sprachen/Umgebungen sind ebenfalls verfügbar.

Wenn Sie sich einige einfache, laufende Beispiele ansehen möchten, schauen Sie sich diese an:

1.2.2.1.3. Überblick über die Architektur#

Der Taler-Software-Stack für einen Händler besteht aus den folgenden Hauptkomponenten:

  • Ein Frontend, das mit dem Browser des Kunden interagiert. Das Frontend ermöglicht es dem Kunden, einen Einkaufswagen zu erstellen und eine Bestellung aufzugeben. Nach der Bezahlung wird die entsprechende Geschäftslogik ausgelöst, um die Bestellung zu erfüllen. Diese Komponente ist nicht im Lieferumfang von Taler enthalten, sondern wird beim Händler vorausgesetzt. Dieses Tutorial beschreibt, wie man ein Taler-Frontend entwickelt.

  • Ein Taler-spezifisches Zahlungs-Backend, das es dem Frontend leicht macht, finanzielle Transaktionen mit Taler zu verarbeiten. Für dieses Tutorial werden Sie ein öffentliches Sandbox-Backend verwenden. Für den produktiven Einsatz müssen Sie entweder Ihr eigenes Backend einrichten oder eine andere Person bitten, dies für Sie zu tun.

Die folgende Abbildung veranschaulicht die verschiedenen Wechselwirkungen zwischen diesen Schlüsselkomponenten:

../../_images/arch-api.png

Das Backend unterstützt das kryptografische Protokoll, speichert Taler-spezifische Finanzinformationen und kommuniziert mit der GNU Taler-Börse über das Internet. Das Frontend greift auf das Backend über eine RESTful API zu. Dadurch muss das Frontend nie direkt mit der Börse kommunizieren und hat auch keinen Umgang mit sensiblen Daten. Insbesondere die Signierschlüssel und Bankkontoinformationen des Händlers sind im Taler-Backend gekapselt.

Einige Funktionen des Backend (die „öffentliche Schnittstelle“) sind dem Browser des Kunden direkt zugänglich. In der HTTP-API sind alle privaten Endpunkte (für das Backoffice) mit dem Präfix /private/ versehen. Dieses Tutorial konzentriert sich auf die /private/ Endpunkte. Die öffentliche Schnittstelle wird direkt von der Geldbörse verwendet und ist für den Händler nicht relevant (außer, dass die API offengelegt werden muss).

1.2.2.1.4. Öffentliches Sandbox-Backend und Authentifizierung#

Wie sich das Frontend gegenüber dem Taler-Backend authentifiziert, hängt von der Konfiguration ab. Siehe Merchant Backend Operator Manual.

Das öffentliche Sandbox-Backend https://backend.demo.taler.net/instances/sandbox/ verwendet einen API-Schlüssel im Authorization-Header. Der Wert dieses Headers muss Bearer secret-token:sandbox für das öffentliche Sandbox-Backend sein.

>>> import requests
>>> requests.get("https://backend.demo.taler.net/instances/sandbox/private/orders",
...              headers={"Authorization": "Bearer secret-token:sandbox"})
<Response [200]>

Wenn ein anderer HTTP-Statuscode als 200 zurückgegeben wird, ist etwas schief gelaufen. Sie sollten herausfinden, was das Problem ist, bevor Sie mit diesem Lernprogramm fortfahren.

Das Sandbox-Backend https://backend.demo.taler.net/instances/sandbox/ verwendet KUDOS als imaginäre Währung. Münzen, die auf KUDOS lauten, können von https://bank.demo.taler.net/ abgehoben werden.

1.2.2.1.5. Merchant Instances#

Ein einzelner Taler-Händler-Backend-Server kann von mehreren Händlern genutzt werden, die separate Geschäftseinheiten sind. Jeder dieser separaten Geschäftseinheiten wird eine Händlerinstanz zugewiesen, die durch eine alphanumerische Instanz-ID identifiziert wird. Wenn die Instanz weggelassen wird, wird die Instanz-ID admin angenommen.

Die folgenden Händlerinstanzen sind auf https://backend.demo.taler.net/ konfiguriert:

Bemerkung

Es handelt sich dabei um fiktive Händler, die für unsere Demonstratoren verwendet werden und nicht mit den jeweiligen Projekten verbunden oder von diesen offiziell anerkannt sind.

Alle Endpunkte für Instanzen bieten die gleiche API. Daher wird die zu verwendende Instanz einfach in die Basis-URL des Händler-Backends aufgenommen.

1.2.2.2. Zahlungsabwicklung für Händler#

1.2.2.2.1. Anlegen eines Auftrags für eine Zahlung#

Zahlungen in Taler basieren auf einer Bestellung, einer maschinenlesbaren Beschreibung des Geschäftsvorfalls, für den die Zahlung erfolgen soll. Bevor Sie als Händler eine Taler-Zahlung akzeptieren, müssen Sie einen solchen Auftrag erstellen.

Dies geschieht durch POSTing eines JSON-Objekts an den API-Endpunkt /private/orders des Backends. Mindestens die folgenden Felder müssen innerhalb des Feldes order angegeben werden:

  • Betrag: Der zu zahlende Betrag, als String im Format CURRENCY:DECIMAL_VALUE, zum Beispiel EUR:10 für 10 Euro oder KUDOS:1.5 für 1.5 KUDOS.

  • Zusammenfassung``: Eine von Menschen lesbare Zusammenfassung, worum es bei der Zahlung geht. Die Zusammenfassung sollte so kurz sein, dass sie in den Titel passt, obwohl es keine feste Grenze gibt.

  • Erfüllungs-Url“: Eine URL, die angezeigt wird, sobald die Zahlung abgeschlossen ist. Bei digitalen Gütern sollte dies eine Seite sein, die das gekaufte Produkt anzeigt. Bei erfolgreicher Zahlung fügt die Wallet automatisch die Order_id als Query-Parameter hinzu, ebenso wie die Session_sig für sitzungsgebundene Zahlungen (siehe unten).

Bestellungen können viele weitere Felder haben, siehe Das Taler-Bestellformat. Wenn Sie eine Bestellung POSTen, können Sie auch zusätzliche Details angeben, wie z.B. einen Override für die Erstattungsdauer und Anweisungen für die Bestandsverwaltung. Diese werden selten benötigt und in diesem Tutorial nicht behandelt; bitte lesen Sie das Referenzhandbuch für Details.

Ein minimales Python-Snippet zur Erstellung einer Bestellung würde wie folgt aussehen:

>>> import requests
>>> 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/instances/sandbox/private/orders",
...               json=body,
...               headers={"Authorization": "Bearer secret-token:sandbox"})
<Response [200]>

Das Backend ergänzt einige Details, die in der Bestellung fehlen, wie z. B. die Adresse der Händlerinstanz. Die vollständigen Details werden als Vertragsbedingungen bezeichnet.

Bemerkung

Die obige Anfrage deaktiviert die Verwendung von Anspruchstoken, indem sie die Option create_token auf false setzt. Wenn Sie Anspruchstoken benötigen, müssen Sie den Code anpassen, um den unten angegebenen URI taler://pay/ so zu konstruieren, dass er das Anspruchstoken enthält.

Nach erfolgreicher POST an /private/orders wird ein JSON mit nur einem Feld order_id mit einer Zeichenkette, welche die Bestell-ID darstellt, zurückgegeben. Wenn Sie auch ein Anspruchstoken erhalten, überprüfen Sie bitte, ob Sie die Anfrage wie oben beschrieben verwendet haben.

Zusammen mit der Instanz des Händlers identifiziert die Bestell-ID die Bestellung eindeutig innerhalb eines Händler-Backends. Mit Hilfe der Bestell-ID können Sie trivialerweise die entsprechende taler://pay/ URI konstruieren, die der Wallet zur Verfügung gestellt werden muss. Lassen Sie example.com den Domainnamen sein, unter dem die öffentlichen Endpunkte der Instanz erreichbar sind. Der Taler pay URI ist dann einfach taler://pay/example.com/$ORDER_ID/, wobei $ORDER_ID durch die ID der zurückgegebenen Bestellung ersetzt werden muss.

Sie können die taler:// URI als Ziel eines Links setzen, um die Taler-Wallet über das taler:// Schema zu öffnen, oder sie in einen QR-Code einfügen. Für einen Webshop ist es jedoch am einfachsten, den Browser einfach auf https://example.com/orders/$ORDER_ID umzuleiten. Diese Seite wird dann die Taler-Wallet auslösen. Hier generiert das Backend die richtige Logik, um die Wallet auszulösen, und unterstützt die verschiedenen Arten von Taler-Wallets. Anstatt die obige URL von Hand zu erstellen, ist es auch möglich, sie durch die Überprüfung des Zahlungsstatus zu erhalten, wie im nächsten Abschnitt beschrieben.

Wenn Sie diese URL manuell erstellen, stellen Sie sicher, dass Sie das Claim-Token angeben (es sei denn, es wurde deaktiviert) und wenn das Backend ohne TLS läuft, verwenden Sie taler+http:// (beachten Sie, dass Letzteres nur von Geldbörsen unterstützt wird, die im Debug-Modus laufen).

Bemerkung

Ein trivialer Weg, die korrekte payment_redirect_url zu erhalten, ist, den Status der Zahlung zu überprüfen (siehe unten). Wenn Sie also immer noch unsicher sind, wie Sie es konstruieren sollen, können Sie einfach das Backend bitten, dies für Sie zu tun. In der Produktion sollten Sie sie aber wahrscheinlich manuell konstruieren und die zusätzliche Anfrage an das Backend vermeiden.

1.2.2.2.2. Überprüfung des Zahlungsstatus und Aufforderung zur Zahlung#

Anhand der Bestell-ID kann der Status einer Zahlung mit dem Endpunkt /private/orders/$ORDER_ID überprüft werden. Wenn die Zahlung durch den Kunden noch nicht abgeschlossen ist, gibt /private/orders/$ORDER_ID dem Frontend eine URL (unter dem Namen payment_redirect_url), die das Wallet des Kunden veranlasst, die Zahlung auszuführen. Dies ist im Grunde die URL https://example.com/orders/$ORDER_ID, die wir oben besprochen haben.

>>> import requests
>>> r = requests.get("https://backend.demo.taler.net/instances/sandbox/private/orders/" + order_id,
...                  headers={"Authorization": "Bearer secret-token:sandbox"})
>>> print(r.json())

Wenn das Feld order_status in der Antwort paid lautet, erhalten Sie keine payment_redirect_url und stattdessen Informationen über den Zahlungsstatus, einschließlich:

  • Vertragsbedingungen: Die vollständigen Vertragsbedingungen der Bestellung.

  • refunded: true, wenn für diesen Kauf eine (möglicherweise teilweise) Rückerstattung gewährt wurde.

  • Erstatteter_Betrag“: Betrag, der erstattet wurde

Sobald das Frontend bestätigt hat, dass die Zahlung erfolgreich war, muss es in der Regel die Geschäftslogik für den Händler auslösen, damit dieser seine Verpflichtungen aus dem Vertrag erfüllen kann.

Bemerkung

Sie müssen die Abfrage nicht ständig wiederholen, um Änderungen des Transaktionsstatus der Bestellung zu bemerken. Die Endpunkte unterstützen lange Abfragen, geben Sie einfach einen timeout_ms Abfrageparameter an, der angibt, wie lange Sie höchstens warten wollen, bis der Bestellstatus auf bezahlt wechselt.

1.2.2.3. Erstattungen gewähren#

Eine Rückerstattung in GNU Taler ist eine Möglichkeit, eine Zahlung „rückgängig“ zu machen. Sie muss vom Händler autorisiert werden. Erstattungen können für jeden Bruchteil des ursprünglich gezahlten Betrags erfolgen, aber sie können die ursprüngliche Zahlung nicht übersteigen. Rückerstattungen sind zeitlich begrenzt und können nur erfolgen, solange die Börse das Geld für eine bestimmte Zahlung auf einem Treuhandkonto hält. Der Zeitraum, in dem eine Rückerstattung möglich ist, kann durch das Setzen der refund_deadline in einem Auftrag kontrolliert werden. Der Standardwert für diese Rückerstattungsfrist wird in der Konfiguration des Backends des Händlers festgelegt.

Das Frontend kann das Backend des Händlers anweisen, eine Rückerstattung zu autorisieren, indem es den Endpunkt /private/orders/$ORDER_ID/refund ansteuert.

Das JSON-Objekt des Erstattungsantrags hat nur zwei Felder:

  • Erstattung“: Der zu erstattende Betrag. Wurde für dieselbe Bestellung eine frühere Erstattung genehmigt, muss der neue Betrag höher sein, andernfalls hat der Vorgang keine Wirkung. Der Wert gibt den zu erstattenden Gesamtbetrag an, nicht eine Erhöhung des Erstattungsbetrags.

  • Begründung“: Von Menschen lesbare Begründung für die Erstattung. Der Grund wird nur vom Back Office verwendet und ist für den Kunden nicht sichtbar.

Wenn die Anfrage erfolgreich ist (angezeigt durch den HTTP-Statuscode 200), enthält die Antwort eine taler_refund_uri. Das Frontend muss den Browser des Kunden auf diese URL umleiten, damit die Erstattung von der Wallet verarbeitet werden kann.

Dieser Codeausschnitt veranschaulicht die Gewährung einer Erstattung:

>>> import requests
>>> refund_req = dict(refund="KUDOS:10",
...                   reason="Customer did not like the product")
>>> requests.post("https://backend.demo.taler.net/instances/sandbox/private/orders/"
...               + order_id + "/refund", json=refund_req,
...               headers={"Authorization": "Bearer secret-token:sandbox"})
<Response [200]>

Bemerkung

Nach der Gewährung einer Rückerstattung ändert der öffentliche Endpunkt https://example.com/orders/$ORDER_ID seine Wallet-Interaktion von der Zahlungsanforderung zum Angebot einer Rückerstattung. Somit können Frontends die Browser wieder zu diesem Endpunkt umleiten. Um dies zu tun, muss jedoch ein h_contract-Feld angehängt werden (?h_contract=$H_CONTRACT), da der öffentliche Endpunkt es zur Authentifizierung des Kunden benötigt. Der erforderliche Wert $H_CONTRACT wird in der Rückerstattungsantwort unter dem Feld h_contract zurückgegeben.

1.2.2.4. Erkennung von Rückkäufen und Erfüllungs-URLs#

Ein mögliches Problem für Händler, die Zugang zu digitalen Artikeln verkaufen, besteht darin, dass ein Kunde möglicherweise für einen Artikel auf einem Gerät bezahlt hat, ihn dann aber auf einem anderen Gerät lesen möchte, möglicherweise einem, auf dem noch nicht einmal eine Taler-Wallet installiert ist.

Natürlich würde der Kunde an dieser Stelle zunächst noch aufgefordert werden, den Artikel erneut zu bezahlen. Öffnet der Kunde dann den Link taler:// in der Wallet, mit der er zuvor den Artikel bezahlt hat (z.B. durch Scannen des QR-Codes auf dem Desktop mit der Android-App), wird die Wallet den Vertrag beanspruchen, erkennen, dass die Fulfillment-URL identisch mit einer ist, für die sie in der Vergangenheit bereits eine Zahlung getätigt hat, und eine Wiederkaufumleitung einleiten: In diesem Fall kontaktiert die Wallet den Händler und wiederholt die vorherige Zahlung, nur dass sie diesmal die (aktuelle) Sitzungs-ID des Browsers verwendet (die Sitzungs-ID erfährt sie aus dem QR-Code).

Das Händler-Backend aktualisiert dann die Sitzungs-ID der bestehenden Bestellung auf die aktuelle Sitzungs-ID des Browsers. Wenn der Zahlungsstatus für die „neue“ unbezahlte Bestellung geprüft wird (oder bereits im Long-Polling ist), stellt das Backend fest, dass für die Session-ID und die Erfüllungs-URL des Browsers ein bereits bezahlter Vertrag besteht. Es weist den Browser dann an, sofort zur Erfüllungs-URL weiterzuleiten, wo der bereits bezahlte Artikel verfügbar ist.

Um sicherzustellen, dass dieser Mechanismus wie vorgesehen funktioniert, müssen Händler darauf achten, dass sie nicht dieselbe Fulfillment-URL für verschiedene Produkte oder für physische Produkte verwenden, bei denen erwartet werden kann, dass die Kunden den Artikel wiederholt kaufen. Ebenso ist es wichtig, dass Händler konsequent dieselbe Fulfillment-URL für dasselbe digitale Produkt verwenden, wenn eine Erkennung von Wiederholungskäufen gewünscht ist.

Beachten Sie, dass die Änderung der Sitzungs-ID auf ein anderes Gerät die Einbeziehung der Geldbörse erfordert, welche die Zahlung getätigt hat, wodurch die Möglichkeit einer breiten gemeinsamen Nutzung der digitalen Käufe angemessen eingeschränkt wird. Die Erkennung eines erneuten Kaufs erfolgt nur für HTTP(S)-URLs zur Erfüllung. Dies bedeutet insbesondere, dass Erfüllungs-URIs wie taler://fulfillment-success/$MESSAGE nicht als Identifizierung einer Ressource betrachtet werden, für die man bezahlen kann, und daher nicht eindeutig sein müssen.

1.2.2.5. Fortgeschrittene Themen#

1.2.2.5.1. Sitzungsgebundene Zahlungen#

Manchmal reicht es nicht aus, nur zu prüfen, ob eine Bestellung bezahlt worden ist. Beim Verkauf von Online-Medien möchte der Herausgeber beispielsweise von jedem Kunden genau dasselbe Produkt bezahlt bekommen. Taler unterstützt dieses Modell, indem es dem Anbieter ermöglicht, zu prüfen, ob der „Zahlungsbeleg“ auf dem aktuellen Gerät des Nutzers verfügbar ist. Dadurch wird verhindert, dass Benutzer den Medienzugang einfach durch Übermittlung eines Links zur Erfüllungsseite freigeben können. Natürlich könnten anspruchsvolle Benutzer auch Zahlungsbelege weitergeben, aber das ist nicht so einfach wie die Weitergabe eines Links, und in diesem Fall ist es wahrscheinlicher, dass sie einfach die Medien direkt weitergeben.

Um diese Funktion zu nutzen, muss der Händler dem aktuellen Browser des Nutzers zunächst eine ephemere „Session_id“ zuweisen, in der Regel über ein Session-Cookie. Bei der Ausführung oder Wiederholung einer Zahlung erhält die Wallet eine zusätzliche Signatur (session_sig). Diese Signatur bescheinigt, dass die Wallet in der aktuellen Sitzung einen Zahlungseingang für die jeweilige Bestellung gezeigt hat.

Sitzungsgebundene Zahlungen werden durch die Übergabe des Parameters „session_id“ an den Endpunkt „check-payment“ ausgelöst. Die Wallet leitet dann auf die Fulfillment-Seite weiter, fügt aber einen zusätzlichen Parameter „session_sig“ hinzu. Das Frontend kann /check-payment sowohl mit der session_id als auch mit der session_sig abfragen, um zu überprüfen, ob die Signatur korrekt ist.

Die letzte Sitzungs-ID, die erfolgreich verwendet wurde, um zu beweisen, dass der Zahlungsbeleg in der Wallet des Benutzers ist, ist auch als last_session_id in der Antwort auf /check-payment verfügbar.

1.2.2.5.2. Identifizierung des Produkts#

In manchen Situationen hat der Nutzer zwar für eine digitale Ware bezahlt, aber das Frontend kennt die genaue Bestell-ID nicht und kann daher die Wallet nicht anweisen, den vorhandenen Zahlungsbeleg offen zu legen. Dies ist häufig bei einfachen Geschäften ohne Login-System der Fall. In diesem Fall würde der Nutzer erneut zur Zahlung aufgefordert werden, obwohl er das Produkt bereits gekauft hat.

Damit die Wallet stattdessen den vorhandenen Zahlungsbeleg finden kann, muss der Shop für jedes Produkt eine eindeutige Fulfillment-URL verwenden. Dann muss das Frontend einen zusätzlichen Parameter resource_url an /check-payment übergeben. Dieser sollte diese eindeutige Fulfillment-URL für das Produkt identifizieren. Die Wallet prüft dann, ob sie schon einmal für einen Vertrag mit der gleichen resource_url bezahlt hat, und wenn ja, wird die vorherige Zahlung wiederholt.

1.2.2.5.3. Das Taler-Format für Aufträge#

In einem Taler-Auftrag können viele Details zur Zahlung angegeben werden. In diesem Abschnitt wird jedes der Felder ausführlich beschrieben.

Finanzbeträge werden immer als String im Format "WÄHRUNG:DEZIMAL_WERT" angegeben.

Betrag

Gibt den Gesamtbetrag an, den der Kunde an den Händler zu zahlen hat.

max_fee

Dies ist der maximale Gesamtbetrag der Einzahlungsgebühren, den der Händler zu zahlen bereit ist. Wenn die Einzahlungsgebühren für die Münzen diesen Betrag übersteigen, muss der Kunde sie in die Gesamtsumme der Zahlung einrechnen. Die Gebühr wird in demselben Format angegeben wie Betrag.

max_wire_fee

Maximale vom Händler akzeptierte Überweisungsgebühr (der Kundenanteil wird durch den Faktor wire_fee_amortization geteilt und weiter reduziert, wenn die Einzahlungsgebühren unter max_fee liegen). Der Standardwert ist Null, wenn er fehlt.

draht_gebühren_amortisation

Über wie viele Kundentransaktionen rechnet der Händler damit, die Überweisungsgebühren im Durchschnitt zu amortisieren? Liegt die Überweisungsgebühr der Börse über der max_wire_fee, wird die Differenz durch diese Zahl geteilt, um den erwarteten Beitrag des Kunden zur Überweisungsgebühr zu berechnen. Der Beitrag des Kunden kann weiter um die Differenz zwischen max_fee und der Summe der tatsächlichen Einzahlungsgebühren reduziert werden. Optional, Standardwert bei Fehlen ist 1. Nullen und negative Werte sind ungültig und werden ebenfalls als 1 interpretiert.

pay_url

Welche URL Zahlungen annimmt. Dies ist die URL, unter der die Wallet Münzen POSTEN wird.

fulfillment_url

Zu welcher URL soll die Wallet gehen, um die Erfüllung zu erhalten, z. B. die HTML- oder PDF-Datei eines gekauften Artikels oder ein System zur Auftragsverfolgung für Sendungen oder eine einfache, von Menschen lesbare Webseite, die den Status des Vertrags angibt.

order_id

Alphanumerische Kennung, die vom Händler frei definiert werden kann. Wird vom Händler zur eindeutigen Identifizierung der Transaktion verwendet.

Zusammenfassung

Kurze, für den Menschen lesbare Zusammenfassung des Vertrags. Zu verwenden, wenn der Vertrag in nur einer Zeile angezeigt werden soll, z. B. in der Transaktionshistorie des Kunden.

Zeitstempel

Zeitpunkt, zu dem das Angebot erstellt wurde.

pay_deadline

Zeitstempel des Zeitpunkts, bis zu dem der Händler möchte, dass die Börse das aus diesem Vertrag fällige Geld endgültig überweist. Nach Ablauf dieser Frist fasst die Börse alle Einzahlungen zusammen, bei denen die Verträge die refund_deadline überschritten haben, und führt eine große Überweisung für sie aus. Die Betraege werden auf die Ueberweisungseinheit abgerundet; wenn der Gesamtbetrag noch unter der Ueberweisungseinheit liegt, wird er nicht ausgezahlt.

rückerstattung_frist

Zeitstempel, bis zu dem der Händler bereit (und in der Lage) ist, Erstattungen für den Vertrag mit Taler zu geben. Beachten Sie, dass die Taler-Börse die Zahlung mindestens bis zu dieser Frist auf einem Treuhandkonto hält. Bis zu diesem Zeitpunkt wird der Händler in der Lage sein, eine Nachricht zu unterschreiben, um eine Rückerstattung an den Kunden auszulösen. Nach diesem Zeitpunkt ist eine Rückerstattung an den Kunden nicht mehr möglich. Muss kleiner sein als die pay_deadline.

Produkte

Array der Produkte, die an den Kunden verkauft werden. Jeder Eintrag enthält ein Tupel mit den folgenden Werten:

Beschreibung

Beschreibung des Produkts.

Menge

Menge der zu versendenden Artikel. Kann eine Einheit (z.B. 1 kg) oder nur die Anzahl angeben.

Preis

Preis für Menge Einheiten dieses Produkts, die an den angegebenen Lieferort geliefert werden. Beachten Sie, dass die Summe aller Preise in der Regel den Gesamtbetrag des Vertrages ergeben sollte, sie kann aber aufgrund von Rabatten oder weil einzelne Preise nicht verfügbar sind, abweichen.

produkt_id

Eindeutige ID des Produkts im Katalog des Händlers. Kann im Allgemeinen frei gewählt werden, da sie nur für den Händler von Bedeutung ist, sollte aber eine Zahl im Bereich [0,2^{51}) sein.

Steuern

Karte der anwendbaren Steuern, die vom Händler zu zahlen sind. Die Bezeichnung ist der Name der Steuer, d. h. Mehrwertsteuer, Umsatzsteuer oder Einkommensteuer, und der Wert ist der anwendbare Steuerbetrag. Beliebige Bezeichnungen sind zulässig, solange sie zur Identifizierung der geltenden Steuerregelung verwendet werden. Die Einzelheiten können von der Aufsichtsbehörde festgelegt werden. Dies dient dazu, dem Kunden zu erklären, welche Steuern der Händler zu zahlen beabsichtigt, und kann vom Kunden als Quittung verwendet werden. Die Informationen werden wahrscheinlich auch bei Steuerprüfungen des Händlers verwendet.

Lieferdatum

Zeitpunkt, zu dem das Produkt an den Lieferort geliefert werden soll.

lieferung_ort

Dies sollte eine Bezeichnung in der Karte Orte ergeben, die angibt, wohin der Gegenstand geliefert werden soll.

Werte können weggelassen werden, wenn sie nicht zutreffend sind. Wenn es sich bei einem Kauf beispielsweise um ein Bündel von Produkten handelt, die keine individuellen Preise oder Produkt-IDs haben, kann die product_id oder der price im Vertrag nicht angegeben werden. Ebenso gibt es für virtuelle Produkte, die direkt über den Fulfillment-URI geliefert werden, keinen Lieferort.

merchant
Adresse

Dies sollte eine Bezeichnung in der Karte Orte ergeben, die angibt, wo sich der Händler befindet.

Name

Dies sollte ein für Menschen lesbarer Name für das Geschäft des Händlers sein.

Gerichtsbarkeit

Dies sollte eine Bezeichnung in der Karte Orte ergeben, welche die Gerichtsbarkeit angibt, unter der dieser Vertrag geschlichtet werden soll.

Standorte

Assoziative Karte der im Vertrag verwendeten Orte. Die Bezeichnungen für die Orte in dieser Karte können frei gewählt und immer dann verwendet werden, wenn ein Ort in anderen Teilen des Vertrages benötigt wird. Auf diese Weise muss derselbe Ort, wenn er mehrfach benötigt wird (z. B. die Geschäftsadresse des Kunden oder des Händlers), nur einmal aufgeführt (und übermittelt) werden und kann ansonsten über die Bezeichnung referenziert werden. Eine nicht erschöpfende Liste von Ortsattributen ist die folgende:

Name

Name des Empfängers für die Zustellung, entweder Firmen- oder Personenname.

Land

Name des Zustellungslandes, wie er auf einem Postpaket steht, z. B. „Frankreich“.

Staat

Name des Zustellungsstaats, wie er auf einem Postpaket steht, z. B. „NY“.

Region

Name der Zustellregion, wie er auf einem Postpaket steht.

Provinzen

Name der zustellenden Provinz, wie er auf einem Postpaket steht.

Stadt

Name des Zustellungsortes, wie er auf einem Postpaket steht.

Postleitzahl

Postleitzahl für die Zustellung, wie sie auf einem Postpaket steht.

Straße

Straßenname für die Zustellung, wie er auf einem Postpaket steht.

Straße_Nummer

Straßennummer (Hausnummer) für die Zustellung, wie sie auf einem Postpaket steht.

Bemerkung

Standorte müssen nicht alle diese Felder angeben und können auch zusätzliche Felder haben. Vertragsrenderer müssen mindestens die oben aufgeführten Felder rendern und sollten Felder, die sie nicht verstehen, als Schlüsselwertliste rendern.