מוכרים יכולים להשתמש באישור תשלום מאובטח (SPC) כחלק מתהליך אימות חזק ללקוח (SCA) בכרטיס אשראי או בחשבון בנק מסוימים. WebAuthn מבצע את האימות (לרוב באמצעות נתונים ביומטריים). יש להירשם מראש ל-WebAuthn. מידע נוסף על כך זמין במאמר רישום אישור תשלום מאובטח.
איך פועל הטמעה טיפוסית
השימוש הנפוץ ביותר ל-SPC הוא כשלקוח מבצע רכישה האתר, ומנפיק כרטיס האשראי או הבנק דורשים אימות של המשלם.
בואו נעבור על תהליך האימות:
- לקוח מספק את פרטי הכניסה שלו לתשלום (למשל כרטיס אשראי). מידע) למוכר.
- המוכר שואל את המנפיק או הבנק המתאימים של פרטי הכניסה
(הצד הנסמך או הגורם המוגבל) אם המשלם צריך אימות נפרד. הזה
עשויה להתרחש, לדוגמה,
EMV® 3-D Secure.
- אם הגורם המוגבל רוצה שהמוכר ישתמש ב-SPC, ואם המשתמש כבר רשומים, הגורם המוגבל (RP) משיב עם רשימה של מזהי פרטי הכניסה שרשומים על ידי המשלם ואתגר.
- אם לא נדרש אימות, המוכר יכול להמשיך אל להשלים את העסקה.
- אם נדרש אימות, המוכר קובע אם הדפדפן תומך ב-SPC.
- אם הדפדפן לא תומך ב-SPC, ממשיכים עם תהליך האימות.
- המוכר מפעיל SPC. בדפדפן תוצג תיבת דו-שיח לאישור.
- אם לא הועברו מזהי פרטי כניסה מה-RP, צריך לחזור אל בתהליך האימות הקיים. לאחר שהאימות בוצע בהצלחה, כדאי להשתמש ברישום SPC כדי לייעל תהליכי אימות עתידיים.
- המשתמש מאשר ומאמת את הסכום ואת היעד של לתשלום על ידי ביטול הנעילה של המכשיר.
- המוכר מקבל פרטי כניסה מהאימות.
- ה-RP מקבל את פרטי הכניסה מהמוכר ומאמת את פרטי הכניסה שלהם האותנטיות.
- הגורם המוגבל שולח את תוצאות האימות למוכר.
- המוכר מציג למשתמש הודעה שמציינת אם התשלום הצלחה או כישלון.
זיהוי תכונות
כדי לזהות אם SPC נתמך בדפדפן, אפשר לשלוח קריאה מזויפת אל
canMakePayment()
כדי לזהות SPC באתר של מוֹכר, צריך להעתיק ולהדביק את הקוד הבא.
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.
}
});
אימות המשתמש
כדי לאמת את המשתמש, יש להפעיל את השיטה PaymentRequest.show()
באמצעות
הפרמטרים secure-payment-confirmation
ו-WebAuthn:
PublicKeyCredentialRequestOptions
- פרמטרים אחרים שהם ספציפיים לתשלום בפלטפורמה של המוֹכר.
אלה הפרמטרים שצריך לספק לנכס data
של אמצעי התשלום, SecurePaymentConfirmationRequest
.
מומלץ לעיין בקוד לדוגמה:
// 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);
}
הפונקציה .show()
תוביל
PaymentResponse
אובייקט, מלבד details
מכיל פרטי כניסה של מפתח ציבורי עם
clientDataJSON
שכולל את נתוני העסקאות
(payment
)
לצורך אימות על ידי הגורם המוגבל.
יש להעביר את פרטי הכניסה שמתקבלים ממקורות שונים ל-RP, מאומת.
איך הגורם המוגבל (RP) מאמת את העסקה
האימות של נתוני העסקאות בשרת RP הוא השלב החשוב ביותר תהליך התשלום.
כדי לאמת את נתוני העסקאות, ה-RP יכול לפעול לפי תהליך האימות של טענת נכוֹנוּת (assertion) של WebAuthn.
בנוסף, הם צריכים
צריך לאמת את payment
.
מטען ייעודי (payload) לדוגמה של 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
תואם למקור של הגורם המוגבל. - הערך
topOrigin
תואם למקור ברמה העליונה שהגורם המוגבל מצפה מקורו של המוכר בדוגמה שלמעלה). - הערך
payeeOrigin
תואם למקור של מקבל התשלום שהיה אמור להיות שמוצגת למשתמש. - הערך
total
תואם לסכום העסקה שצריך היה להציג למשתמש. - הערך
instrument
תואם לפרטים של אמצעי התשלום שאמורים להיות לו הוצגו למשתמש.
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.';
}
אחרי שתעברו את כל קריטריוני האימות, הגורם המוגבל (RP) יוכל לומר ל למוכר שהעסקה בוצעה בהצלחה.
השלבים הבאים
- לקריאת הסקירה הכללית של אישור תשלום מאובטח
- מידע נוסף על הרשמה באמצעות אישור תשלום מאובטח