Verkopers kunnen Secure Payment Confirmation (SPC) gebruiken als onderdeel van een sterk klantauthenticatieproces (SCA) voor een bepaalde creditcard of bankrekening. WebAuthn voert de authenticatie uit (vaak via biometrie). WebAuthn moet vooraf worden geregistreerd. Meer informatie hierover vindt u in ' Een Secure Payment Confirmation registreren' .
Hoe een typische implementatie werkt
SPC wordt het meest gebruikt als een klant een aankoop doet op de site van een handelaar en de creditcarduitgever of bank authenticatie van de betaler vereist.
Laten we het authenticatieproces eens doorlopen:
- Een klant verstrekt zijn betalingsgegevens (zoals creditcardgegevens) aan de verkoper.
- De handelaar vraagt de uitgever of bank (relying party of RP) van de betalingsreferentie of de betaler een aparte authenticatie nodig heeft. Deze uitwisseling kan bijvoorbeeld plaatsvinden met EMV® 3-D Secure .
- Als de RP wil dat de handelaar SPC gebruikt en als de gebruiker zich eerder heeft geregistreerd, stuurt de RP een lijst met de door de betaler geregistreerde inloggegevens en een challenge.
- Als er geen authenticatie nodig is, kan de handelaar de transactie gewoon voltooien.
- Als authenticatie vereist is, bepaalt de handelaar of de browser SPC ondersteunt .
- Als de browser geen SPC ondersteunt, ga dan verder met de bestaande authenticatiestroom.
- De handelaar roept SPC aan. De browser toont een bevestigingsvenster.
- Als er geen referentie-ID's van de RP worden doorgegeven, kunt u terugvallen op de bestaande authenticatieprocedure. Na een succesvolle authenticatie kunt u overwegen om SPC-registratie te gebruiken om toekomstige authenticaties te stroomlijnen .
- De gebruiker bevestigt en authenticeert het bedrag en de bestemming van de betaling door het apparaat te ontgrendelen.
- De handelaar ontvangt een referentie via de authenticatie.
- De RP ontvangt de referenties van de handelaar en controleert of deze authentiek zijn.
- De RP stuurt de verificatieresultaten naar de handelaar.
- De verkoper toont de gebruiker een bericht waarin wordt aangegeven of de betaling is geslaagd of mislukt.
Functiedetectie
Om te controleren of SPC door de browser wordt ondersteund, kunt u een nepoproep naar canMakePayment()
sturen.
Kopieer en plak de volgende code om SPC te detecteren op de website van een verkoper.
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.
}
});
De gebruiker verifiëren
Om de gebruiker te verifiëren, roept u de PaymentRequest.show()
-methode aan met de parameters secure-payment-confirmation
en WebAuthn:
-
PublicKeyCredentialRequestOptions
- Andere betalingsspecifieke parameters op het platform van de handelaar.
Dit zijn de parameters die u moet opgeven voor de data
eigenschap van de betaalmethode, SecurePaymentConfirmationRequest
.
Bekijk deze voorbeeldcode:
// 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);
}
De functie .show()
resulteert in een PaymentResponse
object, behalve dat de details
een openbare sleutelreferentie bevatten met een clientDataJSON
die de transactiegegevens ( payment
) bevat ter verificatie door de RP.
De resulterende referenties moeten cross-origin naar de RP worden overgedragen en geverifieerd.
Hoe de RP de transactie verifieert
Het verifiëren van de transactiegegevens op de RP-server is de belangrijkste stap in het betalingsproces.
Om de transactiegegevens te verifiëren, kan de RP het verificatieproces van WebAuthn volgen. Daarnaast moet de RP de payment
verifiëren .
Een voorbeeld van een payload van 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"
}
}
}
- De
rp
komt overeen met de oorsprong van de RP. - De
topOrigin
komt overeen met de oorsprong op het hoogste niveau die de RP verwacht (de oorsprong van de handelaar in het bovenstaande voorbeeld). - De
payeeOrigin
komt overeen met de oorsprong van de begunstigde die aan de gebruiker getoond had moeten worden. - Het
total
komt overeen met het transactiebedrag dat aan de gebruiker had moeten worden weergegeven. - Het
instrument
komt overeen met de gegevens van het betaalinstrument die aan de gebruiker getoond hadden moeten worden.
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.';
}
Zodra aan alle verificatiecriteria is voldaan, kan de RP de handelaar laten weten dat de transactie is geslaagd.
Volgende stappen
- Lees het overzicht van Veilige Betalingsbevestiging
- Leer meer over registratie met beveiligde betalingsbevestiging