商家可以使用安全付款確認 (SPC) 驗證特定信用卡或銀行帳戶的嚴格客戶驗證 (SCA) 程序。WebAuthn 會執行驗證 (經常透過生物特徵辨識)。您必須預先註冊 WebAuthn,詳情請參閱註冊安全付款確認。
一般實作方式
SPC 最常見的用途是消費者 信用卡發卡機構或銀行要求付款人驗證。
以下說明驗證流程:
- 客戶提供付款憑證 (例如信用卡) 資料) 提供給商家。
- 商家要求付款憑證對應的發卡機構或銀行
則需透過其他方式驗證付款人。這個
舉例來說
EMV® 3-D Secure。
- 是否 RP 要求商家使用 SPC,且使用者先前 受限方所註冊的憑證 ID 清單 付款人和挑戰
- 如果不需要驗證,商家可以繼續 完成交易。
- 如果需要進行驗證,商家可以判斷瀏覽器是否支援 SPC。
- 如果瀏覽器不支援 SPC,請按照現有的 驗證流程
- 商家叫用 SPC。瀏覽器隨即會顯示確認對話方塊。
- 如果沒有從 RP 傳遞的憑證 ID,請改用 現有驗證流程 驗證成功後,建議使用 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 伺服器上驗證交易資料是 付款程序。
為驗證交易資料,RP 可以遵循 WebAuthn 的驗證斷言驗證程序。
另外,他們必須
驗證 payment
。
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
與 RP 的起點相符。topOrigin
符合 RP 預期的頂層起點 ( 商家來源)。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 就能通知 代表交易成功的商家。
後續步驟
- 閱讀安全付款確認總覽
- 瞭解如何透過安全付款確認程序註冊