Người bán có thể sử dụng tính năng Xác nhận thanh toán bảo mật (SPC) trong quy trình xác thực khách hàng nghiêm ngặt (SCA) cho một thẻ tín dụng hoặc tài khoản ngân hàng nhất định. WebAuthn thực hiện việc xác thực (thường là thông qua sinh trắc học). Bạn phải đăng ký trước WebAuthn. Bạn có thể tìm hiểu về cách đăng ký trong bài viết Đăng ký xác nhận thanh toán an toàn.
Cách hoạt động của một phương thức triển khai thông thường
Trường hợp sử dụng SPC phổ biến nhất là khi khách hàng mua hàng trên trang web của người bán và công ty phát hành thẻ tín dụng hoặc ngân hàng yêu cầu xác thực người thanh toán.
Hãy cùng tìm hiểu quy trình xác thực:
- Khách hàng cung cấp thông tin thanh toán (chẳng hạn như thông tin thẻ tín dụng) cho người bán.
- Người bán hỏi công ty phát hành hoặc ngân hàng tương ứng của thông tin thanh toán (bên phụ thuộc hoặc RP) xem người thanh toán có cần xác thực riêng hay không. Ví dụ: việc trao đổi này có thể xảy ra với EMV® 3-D Secure.
- Nếu RP muốn người bán sử dụng SPC và nếu người dùng đã đăng ký trước đó, thì RP sẽ phản hồi bằng danh sách mã thông tin do người thanh toán đăng ký và một thử thách.
- Nếu không cần xác thực, người bán có thể tiếp tục hoàn tất giao dịch.
- Nếu cần xác thực, người bán sẽ xác định xem trình duyệt có hỗ trợ SPC hay không.
- Nếu trình duyệt không hỗ trợ SPC, hãy tiếp tục quy trình xác thực hiện có.
- Người bán gọi SPC. Trình duyệt sẽ hiển thị một hộp thoại xác nhận.
- Nếu không có mã thông tin nào được truyền từ RP, hãy quay lại quy trình xác thực hiện có. Sau khi xác thực thành công, hãy cân nhắc sử dụng tính năng đăng ký SPC để đơn giản hoá các quy trình xác thực trong tương lai.
- Người dùng xác nhận và xác thực số tiền cũng như đích đến của giao dịch thanh toán bằng cách mở khoá thiết bị.
- Người bán sẽ nhận được thông tin xác thực từ quá trình xác thực.
- RP nhận thông tin xác thực từ người bán và xác minh tính xác thực của thông tin đó.
- RP sẽ gửi kết quả xác minh cho người bán.
- Người bán sẽ hiển thị cho người dùng một thông báo cho biết giao dịch thanh toán đã thành công hay không thành công.
Phát hiện tính năng
Để phát hiện xem trình duyệt có hỗ trợ SPC hay không, bạn có thể gửi lệnh gọi giả mạo đến canMakePayment()
.
Sao chép và dán mã sau đây để phát hiện SPC trên trang web của người bán.
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.
}
});
Xác thực người dùng
Để xác thực người dùng, hãy gọi phương thức PaymentRequest.show()
với các tham số secure-payment-confirmation
và WebAuthn:
PublicKeyCredentialRequestOptions
- Các thông số cụ thể về phương thức thanh toán khác trên nền tảng của người bán.
Dưới đây là các tham số bạn nên cung cấp cho thuộc tính data
của phương thức thanh toán, SecurePaymentConfirmationRequest
.
Hãy xem mã ví dụ sau:
// 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);
}
Hàm .show()
sẽ trả về một đối tượng PaymentResponse
, ngoại trừ details
chứa thông tin xác thực khoá công khai với clientDataJSON
chứa dữ liệu giao dịch (payment
) để RP xác minh.
Thông tin xác thực thu được phải được chuyển giữa các nguồn gốc đến RP và được xác minh.
Cách RP xác minh giao dịch
Xác minh dữ liệu giao dịch tại máy chủ RP là bước quan trọng nhất trong quá trình thanh toán.
Để xác minh dữ liệu giao dịch, RP có thể làm theo quy trình xác minh xác nhận xác thực của WebAuthn.
Ngoài ra, họ cần xác minh payment
.
Tải trọng mẫu của 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
khớp với nguồn gốc của RP.topOrigin
khớp với nguồn cấp cao nhất mà RP mong đợi (nguồn của người bán trong ví dụ trên).payeeOrigin
khớp với nguồn gốc của người nhận thanh toán mà người dùng đã thấy.total
khớp với số tiền giao dịch mà người dùng đã thấy.instrument
khớp với thông tin chi tiết về phương thức thanh toán mà người dùng đã thấy.
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.';
}
Sau khi tất cả các tiêu chí xác minh đều đạt, RP có thể thông báo cho người bán rằng giao dịch đã thành công.
Các bước tiếp theo
- Đọc thông tin tổng quan về tính năng Xác nhận thanh toán an toàn
- Tìm hiểu về cách đăng ký bằng tính năng Xác nhận thanh toán an toàn