서비스 워커로 선택적 결제 정보 처리

웹 기반 결제 앱을 웹 결제에 맞게 조정하고 고객에게 더 나은 사용자 환경을 제공하는 방법

웹 기반 결제 앱이 결제 요청을 수신하고 결제 트랜잭션을 시작하면 서비스 워커는 판매자와 결제 앱 간의 통신 허브 역할을 합니다. 이 게시물에서는 결제 앱이 서비스 워커를 사용하여 결제 수단, 배송지 주소 또는 연락처 정보를 판매자에게 전달하는 방법을 설명합니다.

서비스 워커로 선택적 결제 정보 처리
서비스 워커로 선택적 결제 정보 처리

판매자에게 결제 수단 변경 알림

결제 앱은 서로 다른 결제 수단으로 여러 결제 수단을 지원할 수 있습니다.

고객 결제 수단 결제 수단
A 신용카드 발급기관 1 ****1234
신용카드 발급기관 1 ****4242
은행 X ******123
B 신용카드 발급기관 2 ****5678
은행 X ******456

예를 들어 위 표에서 고객 A의 웹 기반 월렛에는 신용카드 두 개와 은행 계좌 하나가 등록되어 있습니다. 이 경우 앱은 세 가지 결제 수단 (****1234, ****4242, ******123)과 두 가지 결제 수단 (신용카드 발급기관 1 및 은행 X)을 처리합니다. 결제 거래에서 결제 앱을 통해 고객은 결제 수단 중 하나를 선택하고 이를 사용하여 판매자 대금을 결제할 수 있습니다.

결제 수단 선택 도구 UI
결제 수단 선택 도구 UI

결제 앱은 전체 결제 응답을 보내기 전에 고객이 선택한 결제 수단을 판매자에게 알릴 수 있습니다. 이 기능은 예를 들어 판매자가 특정 결제 수단 브랜드에 대한 할인 캠페인을 실행하려는 경우에 유용합니다.

Payment Handler API를 사용하면 결제 앱이 서비스 워커를 통해 판매자에게 '결제 수단 변경' 이벤트를 전송하여 새 결제 수단 식별자에 알릴 수 있습니다. 서비스 워커는 새 결제 수단 정보로 PaymentRequestEvent.changePaymentMethod()를 호출해야 합니다.

판매자에게 결제 수단 변경 알림
판매자에게 결제 수단 변경 알림

결제 앱은 methodDetails 객체를 PaymentRequestEvent.changePaymentMethod()의 두 번째 인수(선택사항)로 전달할 수 있습니다. 이 객체에는 판매자가 변경 이벤트를 처리하는 데 필요한 임의의 결제 수단 세부정보가 포함될 수 있습니다.

[결제 핸들러] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'PAYMENT_METHOD_CHANGED':
        const newMethod = e.data.paymentMethod;
        const newDetails = e.data.methodDetails;
        // Redact or check that no sensitive information is passed in
        // `newDetails`.
        // Notify the merchant of the payment method change
        details =
          await payment_request_event.changePaymentMethod(newMethod, newDetails);
      …

판매자는 Payment Request API에서 paymentmethodchange 이벤트를 수신하면 결제 세부정보를 업데이트하고 PaymentDetailsUpdate 객체로 응답할 수 있습니다.

[판매자]

request.addEventListener('paymentmethodchange', e => {
  if (e.methodName === 'another-pay') {
    // Apply $10 discount for example.
    const discount = {
      label: 'special discount',
      amount: {
        currency: 'USD',
        // The value being string complies the spec
        value: '-10.00'
      }
    };
    let total = 0;
    details.displayItems.push(discount);
    for (let item of details.displayItems) {
     total += parseFloat(item.amount.value);
    }
    // Convert the number back to string
    details.total.amount.value = total.toString();
  }
  // Pass a promise to `updateWith()` and send updated payment details
  e.updateWith(details);
});

판매자가 응답하면 PaymentRequestEvent.changePaymentMethod()가 반환한 프로미스가 PaymentRequestDetailsUpdate 객체로 확인됩니다.

[결제 핸들러] service-worker.js

…
        // Notify the merchant of the payment method change
        details = await payment_request_event.changePaymentMethod(newMethod, newDetails);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

객체를 사용하여 프런트엔드의 UI를 업데이트합니다. 업데이트된 결제 세부정보 반영을 참조하세요.

판매자에게 배송지 주소 변경 알리기

결제 앱은 결제 거래의 일환으로 고객의 배송지 주소를 판매자에게 제공할 수 있습니다.

이 기능은 판매자가 주소 수집을 결제 앱에 위임할 수 있으므로 유용합니다. 주소 데이터가 표준 데이터 형식으로 제공되므로 판매자는 일관된 구조로 배송지 주소를 받을 수 있습니다.

또한 고객은 원하는 결제 앱에 주소 정보를 등록하고 이를 여러 판매자에게 재사용할 수 있습니다.

배송지 주소 선택 도구 UI
배송지 주소 선택 도구 UI

결제 앱은 배송지 주소를 수정하거나 결제 거래에서 고객을 위해 사전 등록된 주소 정보를 선택하는 UI를 제공할 수 있습니다. 배송지 주소가 일시적으로 결정되면 결제 앱은 수정된 주소 정보를 판매자에게 알릴 수 있습니다. 이를 통해 판매자에게 다음과 같은 여러 가지 이점이 있습니다.

  • 판매자는 고객이 상품 배송을 위한 지역별 제한사항 (예: 국내만 해당)을 충족하는지 확인할 수 있습니다.
  • 판매자는 배송지 주소의 지역에 따라 배송 옵션 목록을 변경할 수 있습니다 (예: 국제 일반 또는 특급 배송).
  • 판매자는 주소를 기반으로 새 배송비를 적용하고 총 가격을 업데이트할 수 있습니다.

Payment Handler API를 사용하면 결제 앱이 서비스 워커에서 판매자에게 '배송 주소 변경' 이벤트를 전송하여 새 배송지 주소를 알릴 수 있습니다. 서비스 워커는 새 주소 객체와 함께 PaymentRequestEvent.changeShippingAddress()를 호출해야 합니다.

판매자에게 배송지 주소 변경 알리기
판매자에게 배송지 주소 변경 알림

[결제 핸들러] service-worker.js

...
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_ADDRESS_CHANGED':
        const newAddress = e.data.shippingAddress;
        details =
          await payment_request_event.changeShippingAddress(newAddress);
      …

판매자는 Payment Request API에서 shippingaddresschange 이벤트를 수신하므로 업데이트된 PaymentDetailsUpdate로 응답할 수 있습니다.

[판매자]

request.addEventListener('shippingaddresschange', e => {
  // Read the updated shipping address and update the request.
  const addr = request.shippingAddress;
  const details = getPaymentDetailsFromShippingAddress(addr);
  // `updateWith()` sends back updated payment details
  e.updateWith(details);
});

판매자가 응답하면 반환된 프로미스 PaymentRequestEvent.changeShippingAddress()PaymentRequestDetailsUpdate 객체로 확인됩니다.

[결제 핸들러] service-worker.js

…
        // Notify the merchant of the shipping address change
        details = await payment_request_event.changeShippingAddress(newAddress);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

객체를 사용하여 프런트엔드의 UI를 업데이트합니다. 업데이트된 결제 세부정보 반영을 참조하세요.

판매자에게 배송 옵션 변경 알림

배송 옵션은 판매자가 구매한 상품을 고객에게 배송할 때 사용하는 배송 방법입니다. 일반적인 배송 옵션은 다음과 같습니다.

  • 무료 배송
  • 빠른 배송
  • 해외 배송
  • 프리미엄 해외 배송

각각 고유한 비용이 있습니다. 일반적으로 더 빠른 메서드/옵션은 비용이 더 많이 듭니다.

Payment Request API를 사용하는 판매자는 이 선택사항을 결제 앱에 위임할 수 있습니다. 결제 앱은 이 정보를 사용하여 UI를 구성하고 고객이 배송 옵션을 선택하도록 할 수 있습니다.

배송 옵션 선택 도구 UI
배송 옵션 선택 도구 UI

판매자의 Payment Request API에 지정된 배송 옵션 목록은 PaymentRequestEvent의 속성으로 결제 앱의 서비스 워커에 전파됩니다.

[판매자]

const request = new PaymentRequest([{
  supportedMethods: 'https://bobbucks.dev/pay',
  data: { transactionId: '****' }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  shippingOptions: [{
    id: 'standard',
    label: 'Standard',
    amount: { value: '0.00', currency: 'USD' },
    selected: true
  }, {
    id: 'express',
    label: 'Express',
    amount: { value: '5.00', currency: 'USD' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {  requestShipping: true });

결제 앱은 고객이 선택한 배송 옵션을 판매자에게 알릴 수 있습니다. 배송 옵션을 변경하면 총가격도 변경되므로 이는 판매자와 고객 모두에게 중요합니다. 나중에 판매자에게 결제 확인을 위한 최신 가격을 알려야 하며 고객도 변경사항을 알고 있어야 합니다.

Payment Handler API를 사용하면 결제 앱이 서비스 워커에서 판매자에게 '배송 옵션 변경' 이벤트를 전송할 수 있습니다. 서비스 워커는 새 배송 옵션 ID로 PaymentRequestEvent.changeShippingOption()를 호출해야 합니다.

판매자에게 배송 옵션 변경 알림
판매자에게 배송 옵션 변경 알림

[결제 핸들러] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_OPTION_CHANGED':
        const newOption = e.data.shippingOptionId;
        details =
          await payment_request_event.changeShippingOption(newOption);
      …

판매자는 Payment Request API에서 shippingoptionchange 이벤트를 수신합니다. 판매자는 이 정보를 사용하여 총 가격을 업데이트한 다음 업데이트된 PaymentDetailsUpdate를 사용하여 응답해야 합니다.

[판매자]

request.addEventListener('shippingoptionchange', e => {
  // selected shipping option
  const shippingOption = request.shippingOption;
  const newTotal = {
    currency: 'USD',
    label: 'Total due',
    value: calculateNewTotal(shippingOption),
  };
  // `updateWith()` sends back updated payment details
  e.updateWith({ total: newTotal });
});

판매자가 응답하면 PaymentRequestEvent.changeShippingOption()가 반환한 프로미스가 PaymentRequestDetailsUpdate 객체로 확인됩니다.

[결제 핸들러] service-worker.js

…
        // Notify the merchant of the shipping option change
        details = await payment_request_event.changeShippingOption(newOption);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

객체를 사용하여 프런트엔드의 UI를 업데이트합니다. 업데이트된 결제 세부정보 반영을 참조하세요.

업데이트된 결제 세부정보 반영

판매자가 결제 세부정보 업데이트를 완료하면 .changePaymentMethod(), .changeShippingAddress(), .changeShippingOption()에서 반환된 프로미스가 공통 PaymentRequestDetailsUpdate 객체로 확인됩니다. 결제 핸들러는 결과를 사용하여 업데이트된 총가격 및 배송 옵션을 UI에 반영할 수 있습니다.

판매자는 다음과 같은 이유로 오류를 반환할 수 있습니다.

  • 허용되지 않는 결제 수단입니다.
  • 배송지 주소가 지원되는 지역이 아닙니다.
  • 배송지 주소에 잘못된 정보가 포함되어 있습니다.
  • 제공된 배송지 주소 또는 기타 이유로 배송 옵션을 선택할 수 없습니다.

다음 속성을 사용하여 오류 상태를 반영하세요.

  • error: 사람이 읽을 수 있는 오류 문자열입니다. 고객에게 표시하기에 가장 좋은 문자열입니다.
  • shippingAddressErrors: 주소 속성별 자세한 오류 문자열을 포함하는 AddressErrors 객체입니다. 이 방법은 고객이 주소를 수정할 수 있는 양식을 열고 고객을 잘못된 필드로 직접 안내해야 할 때 유용합니다.
  • paymentMethodErrors: 결제 수단별 오류 객체입니다. 판매자에게 구조화된 오류를 제공해 달라고 요청할 수 있지만 웹 결제 사양 작성자는 이를 간단한 문자열로 유지할 것을 권장합니다.

샘플 코드

이 문서에 표시된 샘플 코드는 대부분 다음 작동하는 샘플 앱에서 발췌한 것입니다.

https://paymenthandler-demo.glitch.me

[결제 핸들러] 서비스 워커

[결제 핸들러] 프런트엔드

사용해 보려면 다음 단계를 따르세요.

  1. https://paymentrequest-demo.glitch.me/로 이동합니다.
  2. 페이지 하단으로 이동합니다.
  3. 결제 추가 버튼을 누릅니다.
  4. 결제 수단 식별자 필드에 https://paymenthandler-demo.glitch.me를 입력합니다.
  5. 입력란 옆에 있는 결제 버튼을 누릅니다.