Entwickler · Zahlungen · EUDI-ARF TS12

Zahlungen mit der EUDI-Wallet bestätigen: TS12 Dynamic Linking auf Ihrem eigenen Mandanten

eIDAS 2 (Artikel 5f) verpflichtet Banken und Zahlungsdienstleister, die EUDI-Wallet für die starke Kundenauthentifizierung zu akzeptieren, wenn der Kunde das wünscht. Die Technische Spezifikation 12 (TS12) des EUDI-ARF beschreibt, wie: Die Anfrage enthält die Transaktion, die Wallet zeigt sie an und signiert sie mit dem Schlüssel der Zahlungskarte, und die Bank prüft, dass genau diese Transaktion bestätigt wurde. CodeB führt diese Prüfungen auf Ihrem eigenen Mandanten aus.

OpenID4VP 1.0 · SD-JWT VC · EUDI-ARF TS12 v1.0.1 · in der EU gehostet, Ihr eigener Mandant

Die kurze Antwort

Was
OpenID4VP-Anfragen mit TS12-Transaktionsdaten – Zahlung, Anmeldung oder riskante Aktion, Zugriff auf Kontoinformationen, E-Mandat – und die Prüfung der Antwort der Wallet.
Geprüft
Das TS12-Datenmodell der Transaktion, die Hashes genau der gesendeten Einträge, ein einmaliger Authentifizierungscode, zwei Authentifizierungsfaktoren, der Response-Mode und die Zahlungskarte selbst (Aussteller, Signatur, Sperrstatus).
Ergebnis
Der Authentifizierungscode, die verwendeten Faktoren, die Transaktions-IDs und nur die angefragten Kartenattribute. Niemand wird angemeldet, kein Konto wird angelegt.
Wo
Ihr CodeB-Mandant in der EU. Die Person braucht eine Wallet, die TS12 umsetzt, und eine Zahlungskarte (SCA-Attestation) ihrer Bank.

Die vier TS12-Transaktionstypen

Jede Wallet, die TS12 umsetzt, muss diese vier Typen anzeigen und signieren. Eigene Typnamen Ihrer Bank lassen sich darauf abbilden.

TypWofürPflichtfelder
urn:eudi:sca:payment:1Zahlungsbestätigung: einmalig, terminiert oder wiederkehrend; Konto oder Karte; auch über einen Zahlungsauslösediensttransaction_id, payee (name, id), currency, amount
urn:eudi:sca:login_risk_transaction:1Anmeldung und Aktionen mit Betrugsrisiko, zum Beispiel ein höheres Limittransaction_id, action
urn:eudi:sca:account_access:1Zugriff auf Kontoinformationen, auch über einen Kontoinformationsdiensttransaction_id
urn:eudi:sca:emandate:1E-Mandate, zum Beispiel SEPA-Lastschrifttransaction_id, purpose (oder payment_payload)

So funktioniert es

Derselbe OpenID4VP-Ablauf wie bei der Anmeldung mit der Wallet, mit der Transaktion in der signierten Anfrage.

Transaktion bauen

Ihr Backend baut einen transaction_data-Eintrag: type, credential_ids ["ts12_sca"], transaction_data_hashes_alg ["sha-256"] und die TS12-payload.

Anfrage starten

vp-start mit query=sca, dem Kartentyp und den Einträgen. CodeB prüft die Payload und antwortet mit einem QR-Code-Link und einem Link für dasselbe Telefon zu einer signierten Anfrage.

Die Person bestätigt

Die Wallet zeigt Empfänger, Betrag und die weiteren Felder und signiert mit dem Schlüssel der Karte: Das KB-JWT enthält die Transaktions-Hashes, eine neue jti, die verwendeten Faktoren (amr) und den response_mode.

Sie erhalten das Ergebnis

Fragen Sie vp-response aus demselben Browser ab. Nach allen Prüfungen erhalten Sie den Authentifizierungscode, die Faktoren und die Transaktions-IDs.

Die API

GET /oidc.ashx?action=vp-start&query=scaParameters: vct (type of the SCA attestation, https URL or urn), claims (card attributes to disclose, comma separated, at most 10), transaction_data (base64url of a JSON array of base64url entries, 1–16 entries). Answer {id, request_uri, deep_link}. Errors: 400 invalid_request "transaction_data invalid: ts12_<reason>".
GET /oidc.ashx?action=vp-response&id=<id>Poll from the browser that started the request (same-device cookie). When confirmed: status: completed, claims (requested card attributes, vct, test_credential) and transaction_data (verified, hashes, transaction_ids, sca.authentication_code, sca.amr). Unconfirmed: 403 transaction_data_not_confirmed.
GET /vc/<id>/<version>SD-JWT VC type metadata of a card type issued by this tenant: category urn:eu:europa:ec:eudi:sua:sca and transaction_data_types with labels, display levels and UI labels for the wallet.
Bank-specific typesA transaction type URI of your own can be mapped onto one of the four TS12 data models per tenant; requests with unknown types are refused.

Beispiel

# 1. One transaction_data entry per transaction (TS12 payload), base64url-encoded
{
  "type": "urn:eudi:sca:payment:1",
  "credential_ids": ["ts12_sca"],
  "transaction_data_hashes_alg": ["sha-256"],
  "payload": {
    "transaction_id": "8D8AC610-566D-4EF0-9C22-186B2A5ED793",
    "payee": {"name": "Demo Shop", "id": "DE02120300000000202051"},
    "currency": "EUR",
    "amount": 12.50
  }
}

# 2. Start the request (transaction_data = base64url of the JSON array of the base64url entries)
GET /oidc.ashx?action=vp-start&query=sca&vct=<SCA attestation type>&claims=iban&transaction_data=<...>
-> {"id", "request_uri", "deep_link"}   (QR code or same-phone link)

# 3. After the person confirmed in the wallet: poll from the same browser
GET /oidc.ashx?action=vp-response&id=<id>
-> {"status": "completed",
    "claims": {"iban": "...", "vct": "..."},
    "transaction_data": {"verified": true, "hashes_alg": "sha-256", "hashes": ["..."],
      "transaction_ids": ["8D8AC610-..."],
      "sca": {"authentication_code": "<KB-JWT jti>", "amr": [{"knowledge": "pin_6_or_more_digits"}, {"possession": "key_in_local_native_wscd"}]}}}

OpenAPI (Plattform) · OpenAPI (Plattform)

Was der Server prüft

  • Die Payload gegen das TS12-Datenmodell ihres Typs, einschließlich der Regeln im Text: kein Ausführungsdatum in der Vergangenheit, kein Ausführungsdatum zusammen mit einer Wiederholung, ein Mandatstext, wenn keine Zahlung enthalten ist, ISO-4217-Währung, nur https-Links, keine versteckten Textrichtungszeichen.
  • credential_ids nennen die Zahlungskarten-Abfrage derselben Anfrage; verwendet wird nur sha-256.
  • Das KB-JWT ist mit dem an die Karte gebundenen Schlüssel signiert, und seine transaction_data_hashes sind die SHA-256-Hashes genau der gesendeten Einträge – nicht mehr und nicht weniger.
  • jti wird nur einmal akzeptiert (auch im Cluster) und wird zum Authentifizierungscode; amr nennt mindestens zwei verschiedene Faktorkategorien (Wissen, Besitz, Inhärenz) mit den Werten aus TS12; response_mode entspricht dem der Anfrage.
  • Die Karte selbst: Signatur des Ausstellers, Vertrauenskette, Sperrstatus und der angefragte Typ, genau wie bei jeder Vorlage aus der Wallet.
  • Eine Zahlungsbestätigung entsteht nie aus einer Sitzung mit abgeschwächten Prüfungen oder aus einer Karte, deren Ausstellerkette nicht geprüft werden konnte; die Karte muss als SD-JWT VC kommen.
  • Anfragen ohne Transaktionsdaten sind von keiner dieser Prüfungen betroffen.

Ausprobieren

Die Testseite spielt die Bank oder den Händler: Transaktionstyp wählen, mit der Wallet bestätigen und den erwarteten Hash, den Authentifizierungscode und die Faktoren sehen. Auf phone.codeb.io lässt sich eine Test-Zahlungskarte (Typ https://phone.codeb.io/vc/sca-test-account/1.0) in eine Wallet aufnehmen; sie ist kein Bankkonto, und es fließt kein Geld.

Datenschutz von Anfang an

  • Die Wallet gibt nur die angefragten Kartenattribute heraus; die Transaktionsdetails bleiben zwischen Ihrer Anfrage und der Bestätigung der Person.
  • Eine Zahlungsbestätigung meldet niemanden an, legt kein Konto an und speichert keine Identitätsdaten auf dem Server.
  • Das Ergebnis geht nur an den Browser, der die Anfrage gestartet hat.
  • Das Protokoll hält fest, dass eine Bestätigung stattfand und welche Prüfungen bestanden wurden, nicht Beträge oder Empfänger.
  • Läuft auf Ihrem eigenen CodeB-Mandanten in der EU, ohne Auftragsverarbeiter Dritter.

Ehrliche Grenzen

  • Die Person braucht eine Wallet, die TS12 umsetzt – die Transaktion anzeigt und die Hashes, jti und amr in ihre Antwort aufnimmt. Eine Wallet ohne TS12-Unterstützung lehnt die Anfrage ab.
  • TS12 v1.0.1 gilt für SD-JWT VC; Vorlagen in anderen Formaten werden für Transaktionsdaten nicht akzeptiert.
  • Die Anfrage ist signiert, aber noch nicht verschlüsselt (TS12 empfiehlt Verschlüsselung für Anfragen mit personenbezogenen Daten).
  • CodeB liefert das Authentifizierungsergebnis. Die Ausführung der Zahlung über ein Zahlungsnetz bleibt bei Ihrer Bank oder Ihrem Zahlungsdienst; CodeB beansprucht keine PSD2-Zertifizierung.
  • Die Testkarte auf phone.codeb.io ist nur zum Testen. Echte Zahlungskarten (SCA-Attestations) stellt die Bank der Person aus.

Häufige Fragen

Was ist TS12?

Die Technische Spezifikation 12 des EUDI Architecture and Reference Framework (ARF): wie die starke Kundenauthentifizierung für Zahlungen nach PSD2 mit der EUDI-Wallet funktioniert. Sie legt die Transaktionsdaten in der Anfrage fest, wie die Wallet sie anzeigt und was die Wallet signiert.

Was ist Dynamic Linking?

PSD2 verlangt, dass die Authentifizierung an einen bestimmten Betrag und Empfänger gebunden ist. Mit TS12 signiert die Wallet einen Hash genau der angezeigten Transaktion; ein geänderter Betrag oder Empfänger passt dann nicht mehr.

Was ist der Authentifizierungscode?

Die jti des Key-Binding-JWT der Wallet: ein neuer Zufallswert je Bestätigung. CodeB akzeptiert jeden Wert nur einmal und gibt ihn als Authentifizierungscode zurück.

Welche Wallets funktionieren?

Jede nach dem EUDI-ARF entwickelte Wallet, die TS12 umsetzt und die angefragte Zahlungskarte (SCA-Attestation) besitzt.

Kann meine Bank eigene Transaktionstypen verwenden?

Ja. Eine eigene Typ-URI wird je Mandant auf eines der vier TS12-Datenmodelle abgebildet; der Server prüft sie dann wie die eingebauten Typen.

Bewegt CodeB Geld?

Nein. CodeB prüft die Bestätigung und gibt Ihrem Backend das Ergebnis; die Zahlung selbst läuft über Ihre Bank oder Ihren Zahlungsdienst.

Mit einer Testtransaktion starten

Öffnen Sie die Testseite, nehmen Sie die Test-Zahlungskarte in eine Wallet auf, die TS12 umsetzt, und bestätigen Sie eine Zahlung. Bauen Sie dann dieselbe Anfrage in Ihrem Backend.