Penjual dapat menggunakan Konfirmasi Pembayaran Aman (SPC) sebagai bagian dari proses autentikasi pelanggan yang kuat (SCA) untuk kartu kredit atau rekening bank tertentu. WebAuthn melakukan autentikasi (sering kali melalui biometrik). WebAuthn harus didaftarkan terlebih dahulu, yang dapat Anda pelajari di Mendaftarkan Konfirmasi Pembayaran yang Aman.
Cara kerja implementasi standar
Penggunaan SPC yang paling umum adalah saat pelanggan melakukan pembelian di situs penjual, dan penerbit kartu kredit atau bank mewajibkan autentikasi pembayar.
Mari kita pelajari alur autentikasi:
- Pelanggan memberikan kredensial pembayarannya (seperti informasi kartu kredit) kepada penjual.
- Penjual meminta penerbit atau bank kredensial pembayaran yang sesuai
(pihak tepercaya atau RP) apakah pembayar memerlukan autentikasi terpisah. Pertukaran
ini mungkin terjadi, misalnya, dengan
EMV® 3-D Secure.
- Jika RP ingin penjual menggunakan SPC, dan jika pengguna sebelumnya telah terdaftar, RP akan merespons dengan daftar ID kredensial yang terdaftar oleh pembayar dan tantangan.
- Jika autentikasi tidak diperlukan, penjual dapat terus menyelesaikan transaksi.
- Jika autentikasi diperlukan, penjual menentukan apakah browser mendukung SPC.
- Jika browser tidak mendukung SPC, lanjutkan dengan flow autentikasi yang ada.
- Penjual memanggil SPC. Browser akan menampilkan dialog konfirmasi.
- Jika tidak ada ID kredensial yang diteruskan dari RP, kembali ke alur autentikasi yang ada. Setelah autentikasi berhasil, pertimbangkan untuk menggunakan pendaftaran SPC untuk menyederhanakan autentikasi mendatang.
- Pengguna mengonfirmasi dan mengautentikasi jumlah serta tujuan pembayaran dengan membuka kunci perangkat.
- Penjual menerima kredensial dari autentikasi.
- RP menerima kredensial dari penjual dan memverifikasi keasliannya.
- RP mengirimkan hasil verifikasi ke penjual.
- Penjual menampilkan pesan kepada pengguna untuk menunjukkan apakah pembayaran berhasil atau gagal.
Deteksi fitur
Untuk mendeteksi apakah SPC didukung di browser, Anda dapat mengirim panggilan palsu ke
canMakePayment()
.
Salin dan tempel kode berikut untuk menampilkan deteksi SPC di situs penjual.
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.
}
});
Mengautentikasi pengguna
Untuk mengautentikasi pengguna, panggil metode PaymentRequest.show()
dengan parameter secure-payment-confirmation
dan WebAuthn:
PublicKeyCredentialRequestOptions
- Parameter khusus pembayaran lainnya di platform penjual.
Berikut adalah parameter yang harus Anda berikan ke properti data
metode pembayaran, SecurePaymentConfirmationRequest
.
Lihat kode contoh ini:
// 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);
}
Fungsi .show()
menghasilkan objek
PaymentResponse
kecuali details
berisi kredensial kunci publik dengan
clientDataJSON
yang berisi data transaksi
(payment
)
untuk verifikasi oleh RP.
Kredensial yang dihasilkan harus ditransfer lintas origin ke RP dan diverifikasi.
Cara RP memverifikasi transaksi
Memverifikasi data transaksi di server RP adalah langkah terpenting dalam proses pembayaran.
Untuk memverifikasi data transaksi, RP dapat mengikuti proses verifikasi pernyataan autentikasi WebAuthn.
Selain itu, mereka perlu
memverifikasi payment
.
Contoh 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
cocok dengan asal RP.topOrigin
cocok dengan origin tingkat teratas yang diharapkan RP (origin penjual dalam contoh di atas).payeeOrigin
cocok dengan asal penerima pembayaran yang seharusnya ditampilkan kepada pengguna.total
cocok dengan jumlah transaksi yang seharusnya ditampilkan kepada pengguna.instrument
cocok dengan detail instrumen pembayaran yang seharusnya ditampilkan kepada pengguna.
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.';
}
Setelah semua kriteria verifikasi lulus, RP dapat memberi tahu penjual bahwa transaksi berhasil.
Langkah berikutnya
- Baca ringkasan Konfirmasi Pembayaran Aman
- Pelajari pendaftaran dengan Konfirmasi Pembayaran Aman