Güvenli Ödeme Onayı ile kimliğinizi doğrulayın

Satıcılar, belirli bir kredi kartı veya banka hesabı için güçlü bir müşteri kimlik doğrulama (SCA) işleminin bir parçası olarak Güvenli Ödeme Onayı'nı (SPC) kullanabilir. WebAuthn, kimlik doğrulamayı gerçekleştirir (genellikle biyometri aracılığıyla). WebAuthn'un önceden kaydedilmesi gerekir. Bu konuda daha fazla bilgiye Güvenli Ödeme Onayı Kaydetme bölümünden ulaşabilirsiniz.

Tipik bir uygulamanın işleyiş şekli

SPC için en yaygın kullanım, müşterinin satıcının sitesinde satın alma işlemi gerçekleştirmesi ve kredi kartını veren kuruluşun veya bankanın ödeme yapan tarafın kimlik doğrulamasını zorunlu kılmasıdır.

Kimlik doğrulama iş akışı.

Kimlik doğrulama akışını adım adım inceleyelim:

  1. Müşteri, ödeme kimlik bilgilerini (kredi kartı bilgileri gibi) satıcıya sağlar.
  2. Satıcı, ödeme yapan kişinin ayrı bir kimlik doğrulamasına ihtiyacı olup olmadığını öğrenmek için ödeme belgesinin ilgili kuruluşunu veya bankayı (bağlı taraf veya RP) ister. Bu değişim, örneğin EMV® 3-D Secure ile gerçekleşebilir.
    • RP, satıcının SPC kullanmasını isterse ve kullanıcı daha önce kayıt yaptırdıysa RP ödeme yapan tarafın kaydettiği kimlik bilgileri listesi ve bir giriş sorgulamasıyla yanıt verir.
    • Kimlik doğrulama gerekmiyorsa satıcı işlemi tamamlamaya devam edebilir.
  3. Kimlik doğrulama gerektiğinde tarayıcının SPC'yi destekleyip desteklemediğini satıcı belirler.
    • Tarayıcı SPC'yi desteklemiyorsa mevcut kimlik doğrulama akışıyla devam edin.
  4. Satıcı SPC'yi çağırır. Tarayıcıda bir onay iletişim kutusu görüntülenir.
    • Kısıtlanmış taraftan geçirilen kimlik bilgisi kimliği yoksa mevcut kimlik doğrulama akışına geçin. Başarılı bir kimlik doğrulamasından sonra gelecekteki kimlik doğrulama işlemlerini kolaylaştırmak için SPC kaydını kullanabilirsiniz.
  5. Kullanıcı, cihazın kilidini açarak ödemenin tutarını ve hedefini onaylar ve doğrular.
  6. Satıcı, kimlik doğrulamadan bir kimlik bilgisi alır.
  7. Kısıtlanmış taraf, kimlik bilgisini satıcıdan alır ve orijinalliğini doğrular.
  8. Kısıtlanmış taraf, doğrulama sonuçlarını satıcıya gönderir.
  9. Satıcı, kullanıcıya ödemenin başarılı mı yoksa başarısız mı olduğunu belirten bir mesaj gösterir.

Özellik algılama

Tarayıcıda SPC'nin desteklenip desteklenmediğini tespit etmek için canMakePayment() numarasına sahte bir çağrı gönderebilirsiniz.

Satıcının web sitesinde SPC'yi algılama özelliğini kullanmak için aşağıdaki kodu kopyalayıp yapıştırı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.
  }
});

Kullanıcının kimliğini doğrulama

Kullanıcının kimliğini doğrulamak için secure-payment-confirmation ve WebAuthn parametreleriyle PaymentRequest.show() yöntemini çağırın:

Ödeme yönteminin data özelliğine (SecurePaymentConfirmationRequest) sağlamanız gereken parametreler aşağıda belirtilmiştir.

Parametre Açıklama
rpId Kısıtlanmış taraf kimliği olarak RP kaynağının ana makine adı.
challenge Saldırıların tekrarlanmasını önleyen rastgele bir meydan okuma.
credentialIds Kimlik bilgisi kimlikleri dizisi. WebAuthn'un kimlik doğrulamasında allowCredentials mülkü bir dizi PublicKeyCredentialDescriptor nesnesini kabul eder, ancak SPC'de yalnızca kimlik bilgisi kimliklerinin listesini iletirsiniz.
payeeName (isteğe bağlı) Alacaklı adı.
payeeOrigin Alacaklının kaynağı. Yukarıda belirtilen senaryoda bu, satıcının kaynağıdır.
instrument displayName için bir dize ve icon için bir resim kaynağına işaret eden URL. iconMustBeShown için bir simgenin başarıyla getirilmesini ve isteğin başarılı olması için bir simgenin gösterilmesi gerektiğini belirten isteğe bağlı bir boole değeri (varsayılan olarak true değerine ayarlanır).
timeout İşlemi imzalamak için zaman aşımı (milisaniye cinsinden)
extensions WebAuthn çağrısına uzantılar eklendi. "Ödeme" uzantısını kendiniz belirtmeniz gerekmez.

Şu örnek kodu inceleyin:

// 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() işlevi, PaymentResponse nesnesi oluşturur. Ancak details, RP tarafından doğrulanmak üzere işlem verilerini (payment) içeren clientDataJSON içeren bir ortak anahtar kimlik bilgisi içerir.

Oluşturulan kimlik bilgisi, kaynaklar arası RP'ye aktarılmalı ve doğrulanmalıdır.

Kısıtlanmış taraf işlemi nasıl doğrular?

Kısıtlanmış taraf sunucusundaki işlem verilerinin doğrulanması, ödeme sürecinin en önemli adımıdır.

Kısıtlanmış taraf, işlem verilerini doğrulamak için WebAuthn'un kimlik doğrulama onayı doğrulama sürecini izleyebilir. Ayrıca, payment doğrulaması gerekir.

Örnek clientDataJSON yükü:

{
  "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, kısıtlanmış tarafın kaynağı ile eşleşiyor.
  • topOrigin, RP'nin beklediği üst düzey kaynakla eşleşir (yukarıdaki örnekte satıcının kaynağı).
  • payeeOrigin, kullanıcıya gösterilmesi gereken alacaklının kaynağıyla eşleşir.
  • total, kullanıcıya gösterilmesi gereken işlem tutarıyla eşleşir.
  • instrument, kullanıcıya gösterilmesi gereken ödeme aracı ayrıntılarıyla eşleşir.
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.';
}

Tüm doğrulama ölçütleri karşılandıktan sonra, Kısıtlanmış Taraf satıcıya işlemin başarılı olduğunu söyleyebilir.

Sonraki adımlar