Mit sicherer Zahlungsbestätigung authentifizieren

Händler können die sichere Zahlungsbestätigung (Secure Payment Confirmation, SPC) als Teil einer starken Kundenauthentifizierung (SCA) für eine bestimmte Kreditkarte oder ein bestimmtes Bankkonto verwenden. WebAuthn führt die Authentifizierung durch (häufig über biometrisches Verfahren). WebAuthn muss im Voraus registriert werden. Weitere Informationen dazu finden Sie unter Registrieren einer sicheren Zahlungsbestätigung.

So funktioniert eine typische Implementierung

SPC wird am häufigsten verwendet, wenn ein Kunde einen Kauf im und der Kreditkartenaussteller bzw. die Bank verlangt die Authentifizierung des Zahlungspflichtigen.

Authentifizierungsworkflow.

Gehen wir die Authentifizierung durch:

  1. Ein Kunde stellt seine Zahlungsinformationen zur Verfügung (z. B. Kreditkarte). Informationen) an den Händler.
  2. Der Händler fragt den entsprechenden Aussteller oder die entsprechende Bank des Ausweisdokuments. (die vertrauende Seite oder RP), wenn der Zahlungspflichtige eine separate Authentifizierung benötigt. Dieses z. B. durch eine EMV® 3-D Secure.
    • Wenn der Händler laut RP SPC verwenden soll und der Nutzer registriert, antwortet der RP mit einer Liste von Ausweisdokument-IDs, die von den Zahlungspflichtigen und eine Herausforderung.
    • Wenn keine Authentifizierung erforderlich ist, kann der Händler um die Transaktion abzuschließen.
  3. Wenn eine Authentifizierung erforderlich ist, ermittelt der Händler, ob der Browser SPC unterstützt.
    • Wenn der Browser SPC nicht unterstützt, fahren Sie mit dem vorhandenen Authentifizierungsvorgangs.
  4. Der Händler ruft SPC auf. Im Browser wird ein Bestätigungsdialogfeld angezeigt.
    • Wenn keine Ausweisdokument-IDs vom RP weitergegeben werden, verwenden Sie die vorhandenen Authentifizierungsablauf. Nach einer erfolgreichen Authentifizierung können Sie die SPC-Registrierung verwenden. um zukünftige Authentifizierungen zu optimieren.
  5. Der Nutzer bestätigt und authentifiziert den Betrag und das Ziel des indem du das Gerät entsperrst.
  6. Der Händler erhält einen Berechtigungsnachweis von der Authentifizierung.
  7. Das RP erhält die Anmeldedaten vom Händler und verifiziert seine Authentizität.
  8. Das RP sendet die Bestätigungsergebnisse an den Händler.
  9. Der Händler zeigt dem Nutzer eine Nachricht, in der er angibt, ob die Zahlung erfolgreich oder nicht erfolgreich war.

Funktionserkennung

Um festzustellen, ob SPC im Browser unterstützt wird, können Sie einen gefälschten Anruf an canMakePayment()

Kopieren Sie den folgenden Code und fügen Sie ihn ein, um SPC auf der Website eines Händlers zu erkennen.

const isSecurePaymentConfirmationSupported = async () => {
  if (!'PaymentRequest' in window) {
    return [false, 'Payment Request API is not supported'];
  }

  try {
    // The data below is the minimum required to create the request and
    // check if a payment can be made.
    const supportedInstruments = [
      {
        supportedMethods: "secure-payment-confirmation",
        data: {
          // RP's hostname as its ID
          rpId: 'rp.example',
          // A dummy credential ID
          credentialIds: [new Uint8Array(1)],
          // A dummy challenge
          challenge: new Uint8Array(1),
          instrument: {
            // Non-empty display name string
            displayName: ' ',
            // Transparent-black pixel.
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==',
          },
          // A dummy merchant origin
          payeeOrigin: 'https://non-existent.example',
        }
      }
    ];

    const details = {
      // Dummy shopping details
      total: {label: 'Total', amount: {currency: 'USD', value: '0'}},
    };

    const request = new PaymentRequest(supportedInstruments, details);
    const canMakePayment = await request.canMakePayment();
    return [canMakePayment, canMakePayment ? '' : 'SPC is not available'];
  } catch (error) {
    console.error(error);
    return [false, error.message];
  }
};

isSecurePaymentConfirmationSupported().then(result => {
  const [isSecurePaymentConfirmationSupported, reason] = result;
  if (isSecurePaymentConfirmationSupported) {
    // Display the payment button that invokes SPC.
  } else {
    // Fallback to the legacy authentication method.
  }
});

Nutzer authentifizieren

Rufen Sie zum Authentifizieren des Nutzers die Methode PaymentRequest.show() mit secure-payment-confirmation- und WebAuthn-Parameter:

Hier sind die Parameter, die du für die data-Property SecurePaymentConfirmationRequest der Zahlungsmethode angeben solltest.

Parameter Beschreibung
rpId Der Hostname des RP-Ursprungs als RP-ID.
challenge Eine zufällige Herausforderung, die Replay-Angriffe verhindert.
credentialIds Ein Array von Ausweisdokument-IDs. Bei der WebAuthn-Authentifizierung akzeptiert das Attribut allowCredentials ein Array von PublicKeyCredentialDescriptor-Objekten, aber bei SPC übergeben Sie nur eine Liste mit Anmeldedaten-IDs.
payeeName (optional) Name des Zahlungsempfängers
payeeOrigin Der Ursprung des Zahlungsempfängers. Im oben genannten Szenario ist es der Ursprungsort des Händlers.
instrument Ein String für displayName und eine URL für icon, die auf eine Bildressource verweisen. Ein optionaler boolescher Wert (standardmäßig true) für iconMustBeShown, der ein Symbol angibt, muss erfolgreich abgerufen und angezeigt werden, damit die Anfrage erfolgreich ausgeführt werden kann.
timeout Zeitlimit zum Signieren der Transaktion in Millisekunden
extensions Erweiterungen wurden dem WebAuthn-Aufruf hinzugefügt. „Zahlung“ muss nicht angegeben werden. Erweiterung selbst.

Schauen Sie sich diesen Beispielcode an:

// After confirming SPC is available on this browser via a feature detection,
// fetch the request options cross-origin from the RP server.
const options = fetchFromServer('https://rp.example/spc-auth-request');
const { credentialIds, challenge } = options;

const request = new PaymentRequest([{
  // Specify `secure-payment-confirmation` as payment method.
  supportedMethods: "secure-payment-confirmation",
  data: {
    // The RP ID
    rpId: 'rp.example',

    // List of credential IDs obtained from the RP server.
    credentialIds,

    // The challenge is also obtained from the RP server.
    challenge,

    // A display name and an icon that represent the payment instrument.
    instrument: {
      displayName: "Fancy Card ****1234",
      icon: "https://rp.example/card-art.png",
      iconMustBeShown: false
    },

    // The origin of the payee (merchant)
    payeeOrigin: "https://merchant.example",

    // The number of milliseconds to timeout.
    timeout: 360000,  // 6 minutes
  }
}], {
  // Payment details.
  total: {
    label: "Total",
    amount: {
      currency: "USD",
      value: "5.00",
    },
  },
});

try {
  const response = await request.show();

  // response.details is a PublicKeyCredential, with a clientDataJSON that
  // contains the transaction data for verification by the issuing bank.
  // Make sure to serialize the binary part of the credential before
  // transferring to the server.
  const result = fetchFromServer('https://rp.example/spc-auth-response', response.details);
  if (result.success) {
    await response.complete('success');
  } else {
    await response.complete('fail');
  }
} catch (err) {
  // SPC cannot be used; merchant should fallback to traditional flows
  console.error(err);
}

Die Funktion .show() führt zu einem PaymentResponse mit Ausnahme des details-Objekts, das Anmeldedaten mit öffentlichem Schlüssel mit einem clientDataJSON, die die Transaktionsdaten enthält (payment) zur Überprüfung durch das RP.

Die resultierenden Anmeldedaten müssen ursprungsübergreifend an die RP übertragen werden und bestätigt.

So bestätigt der RP die Transaktion

Die Verifizierung der Transaktionsdaten auf dem RP-Server ist der wichtigste Schritt des Zahlungsprozesses.

Zur Verifizierung der Transaktionsdaten kann der RP dem Authentifizierungs-Assertion-Überprüfungsprozess von WebAuthn folgen. Darüber hinaus müssen sie bestätigen Sie die payment.

Beispielnutzlast von clientDataJSON:

{
  "type":"payment.get",
  "challenge":"SAxYy64IvwWpoqpr8JV1CVLHDNLKXlxbtPv4Xg3cnoc",
  "origin":"https://spc-merchant.glitch.me",
  "crossOrigin":false,
  "payment":{
    "rp":"spc-rp.glitch.me",
    "topOrigin":"https://spc-merchant.glitch.me",
    "payeeOrigin":"https://spc-merchant.glitch.me",
    "total":{
      "value":"15.00",
      "currency":"USD"
    },
    "instrument":{
      "icon":"https://cdn.glitch.me/94838ffe-241b-4a67-a9e0-290bfe34c351%2Fbank.png?v=1639111444422",
      "displayName":"Fancy Card 825809751248"
    }
  }
}
  • rp entspricht dem Ursprung des RP.
  • topOrigin stimmt mit dem Ursprung auf oberster Ebene überein, den die RP erwartet (der Ursprung des Händlers im obigen Beispiel angegeben.
  • Die payeeOrigin entspricht dem Ursprung des Zahlungsempfängers. die der Nutzer sieht.
  • total stimmt mit dem Transaktionsbetrag überein, der hätte angezeigt werden sollen. für den Nutzer.
  • Die instrument stimmt mit den Angaben zum Zahlungsmittel überein, die Folgendes enthalten sollten: die dem Nutzer angezeigt wurden.
const clientData = base64url.decode(response.clientDataJSON);
const clientDataJSON = JSON.parse(clientData);

if (!clientDataJSON.payment) {
  throw 'The credential does not contain payment payload.';
}

const payment = clientDataJSON.payment;
if (payment.rp !== expectedRPID ||
    payment.topOrigin !== expectedOrigin ||
    payment.payeeOrigin !== expectedOrigin ||
    payment.total.value !== '15.00' ||
    payment.total.currency !== 'USD') {
  throw 'Malformed payment information.';
}

Nachdem alle Überprüfungskriterien erfüllt sind, kann der RP den Händler bestätigen, dass die Transaktion erfolgreich war.

Nächste Schritte