Sprzedawcy mogą używać bezpiecznego potwierdzenia płatności (SPC) w ramach procesu silnego uwierzytelniania klienta (SCA) w przypadku danej karty kredytowej lub konta bankowego. WebAuthn przeprowadza uwierzytelnianie (często za pomocą danych biometrycznych). WebAuthn musi być zarejestrowany z wyprzedzeniem. Więcej informacji znajdziesz w artykule Rejestrowanie bezpiecznego potwierdzenia płatności.
Jak działa typowa implementacja
Najczęstszym zastosowaniem SPC jest sytuacja, gdy klient dokonuje zakupu w witrynie sprzedawcy, a wydawca karty kredytowej lub bank wymaga uwierzytelnienia płatnika.
Omówmy proces uwierzytelniania:
- Klient przekazuje sprzedawcy dane do płatności (np. informacje o karcie kredytowej).
- Sprzedawca pyta wydawcę lub bank odpowiadający za dane uwierzytelniające płatności (stroną zaufaną lub RP), czy płatnik potrzebuje osobnego uwierzytelnienia. Takie wymiany mogą na przykład mieć miejsce w przypadku EMV® 3-D Secure.
- Jeśli RP chce, aby sprzedawca korzystał z SPC, a użytkownik został wcześniej zarejestrowany, RP odpowiada listą identyfikatorów danych logowania zarejestrowanych przez płatnika oraz wyzwaniem.
- Jeśli uwierzytelnianie nie jest wymagane, sprzedawca może kontynuować realizację transakcji.
 
- Jeśli uwierzytelnianie jest wymagane, sprzedawca decyduje, czy przeglądarka obsługuje SPC.
- Jeśli przeglądarka nie obsługuje SPC, przejdź do bieżącego procesu uwierzytelniania.
 
- Sprzedawca wywołuje usługę SPC. Przeglądarka wyświetli okno potwierdzenia.
- Jeśli z serwera RP nie otrzymasz żadnych identyfikatorów danych uwierzytelniających, użyj istniejącego procesu uwierzytelniania. Po pomyślnym uwierzytelnieniu rozważ użycie rejestracji w SPC, aby usprawnić przyszłe uwierzytelnianie.
 
- Użytkownik potwierdza i uwierzytelnia kwotę oraz miejsce docelowe płatności, odblokowując urządzenie.
- Sprzedawca otrzymuje dane uwierzytelniające.
- RP otrzymuje dane logowania od sprzedawcy i weryfikuje ich autentyczność.
- RP wysyła wyniki weryfikacji do sprzedawcy.
- Sprzedawca wyświetla użytkownikowi wiadomość, która informuje, czy płatność została zrealizowana, czy nie.
Wykrywanie funkcji
Aby sprawdzić, czy przeglądarka obsługuje SPC, możesz wysłać fałszywe wywołanie do canMakePayment().
Skopiuj i wklej ten kod, aby wykryć SPC w witrynie sprzedawcy.
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.
  }
});
Uwierzytelnienie użytkownika
Aby uwierzytelnić użytkownika, wywołaj metodę PaymentRequest.show() z parametrami secure-payment-confirmation i WebAuthn:
- PublicKeyCredentialRequestOptions
- inne parametry płatności na platformie sprzedawcy.
Oto parametry,  które należy podać w przypadku właściwości data formy płatności: SecurePaymentConfirmationRequest.
Sprawdź ten przykładowy kod:
// 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);
}
Funkcja .show() zwraca obiekt PaymentResponse, z tym że details zawiera klucz publiczny z clientDataJSON, który zawiera dane transakcji (payment) do weryfikacji przez RP.
Uzyskane dane uwierzytelniające muszą zostać przeniesione do RP w innej domenie i zweryfikowane.
Jak RP weryfikuje transakcję
Weryfikacja danych transakcji na serwerze RP jest najważniejszym krokiem w procesie płatności.
Aby zweryfikować dane transakcji, RP może wykonać proces weryfikacji oświadczenia uwierzytelniającego w WebAuthn.
Dodatkowo musisz potwierdzić payment.
Przykładowy ładunek 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"
    }
  }
}
- rppasuje do źródła RP.
- Wartość topOriginodpowiada domencie najwyższego poziomu oczekiwanemu przez RP (w przykładzie powyżej jest to domena sprzedawcy).
- Wartość payeeOriginodpowiada źródłu danych odbiorcy płatności, które powinny zostać wyświetlone użytkownikowi.
- Wartość totalodpowiada kwocie transakcji, która powinna zostać wyświetlona użytkownikowi.
- Wartość instrumentodpowiada szczegółom instrumentu płatniczego, które powinny zostać wyświetlone użytkownikowi.
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.';
}
Gdy wszystkie kryteria weryfikacji zostaną spełnione, RP może poinformować sprzedawcę, że transakcja została zrealizowana.
Dalsze kroki
- Zapoznaj się z ogólnymi informacjami o potwierdzenie płatności za pomocą bezpiecznej płatności.
- Dowiedz się więcej o rejestracji w ramach Bezpiecznego potwierdzenia płatności.
