웹 기반 결제 핸들러 API

W3C 워킹 드래프트

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2026/WD-web-based-payment-handler-20260218/
최신 공식 버전:
https://www.w3.org/TR/web-based-payment-handler/
최신 에디터스 드래프트:
https://w3c.github.io/web-based-payment-handler/
히스토리:
https://www.w3.org/standards/history/web-based-payment-handler/
커밋 히스토리
테스트 스위트:
https://wpt.live/payment-handler/
에디터:
Ian Jacobs (W3C)
Jinho Bang (초청 전문가)
Stephen McGruer (Google)
이전 에디터:
Andre Lyver (Shopify)
Tommy Thorsen (Opera)
Adam Roach (Mozilla)
Rouslan Solomakhin (Google)
Adrian Hope-Bailie (Coil)
피드백:
GitHub w3c/web-based-payment-handler (풀 리퀘스트, 이슈 등록, 오픈 이슈)

요약

이 명세서는 웹 애플리케이션이 결제 요청을 처리할 수 있도록 하는 기능을 정의합니다.

문서의 상태

이 섹션은 이 문서가 게시될 당시의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 찾을 수 있습니다.

웹 결제 작업 그룹은 그룹이 아직 처리하지 않은 모든 버그 보고서 목록을 유지합니다. 이 초안은 작업 그룹에서 여전히 논의되어야 하는 일부 보류 중인 문제를 강조합니다. 이러한 문제들의 결과(유효성 여부 포함)에 대해 어떠한 결정도 내려지지 않았습니다. 미해결 문제에 대해 제안된 명세 텍스트가 포함된 풀 리퀘스트 제출을 적극 권장합니다.

이 문서는 Web Payments Working Group에 의해 권고 경로(Recommendation track)를 사용하여 작업 초안으로 게시되었습니다.

작업 초안으로서의 게시가 W3C와 그 구성원의 승인(endorsement)을 의미하지는 않습니다.

이 문서는 초안이며 언제든지 업데이트, 교체 또는 다른 문서에 의해 대체될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않습니다.

이 문서는 다음의 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C 특허 정책에 따라 제작되었습니다.

W3C는 그룹의 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 유지합니다. 해당 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 개인이 본인이 핵심 청구항(Essential Claim(s))을 포함한다고 믿는 특허에 대해 실제로 알고 있는 경우, 해당 정보는 W3C 특허 정책의 섹션 6에 따라 공개해야 합니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서에 의해 규율됩니다.

1. 소개

이 섹션은 비규범적입니다.

이 명세서는 웹 애플리케이션이 사용자를 대신하여 결제 요청을 처리할 수 있도록 하기 위해 다음과 같은 새로운 기능들을 정의합니다:

참고

이 명세서는 운영체제 특정 메커니즘(예: "네이티브 앱")으로 구축된 소프트웨어가 결제 요청을 어떻게 처리하는지는 다루지 않습니다.

2. 개요

이 문서에서는 다음과 같은 흐름을 가정합니다:

  1. 하나의 출처(origin)가 사용자의 허락을 받아, 지원하는 결제 수단 집합에 대한 결제 요청을 처리할 수 있는 권한을 요청합니다. 예를 들어, 사용자가 리테일러나 은행 사이트를 방문했을 때 해당 출처에서 웹 기반 결제 핸들러를 등록하라는 메시지가 표시될 수 있습니다. 출처는 권한의 범위를 설정하지만, 출처의 기능은 추가적인 사용자 동의 없이도 진화할 수 있습니다.
  2. 웹 기반 결제 핸들러서비스 워커 코드에서 정의됩니다.
  3. 머천트(또는 다른 수취인(payee))가 [payment-request]의 canMakePayment() 또는 show() 메서드를 호출하면(예: 사용자인 지불인(payer)이 체크아웃 페이지에서 버튼을 누를 때), 사용자 에이전트는 웹 기반 결제 핸들러 후보 목록을 계산합니다. 이 때 머천트가 허용하는 결제 방식과 사용자 에이전트가 알고 있는(단, 이 방법에 국한되지 않음) 결제 방식이 비교됩니다:
    • 이 API를 통해 미리 등록된 결제 수단.
    • 거래 도중에 이 API를 통해 등록될 수 있는 결제 수단(예: payment method manifest에서 식별된 경우).
    • 운영체제 등 다른 메커니즘을 통해 등록된 결제 수단.
  4. 사용자 에이전트가 후보 결제 핸들러 목록을 사용자에게 표시합니다. 이 선택지는 등록 시점에 제공된 정보(라벨 및 아이콘) 또는 Web 앱에서 사용할 수 있는 정보를 사용해 표시됩니다.
  5. 지불인(payer) 사용자가 웹 기반 결제 핸들러를 선택하면, 사용자 에이전트는 해당 웹 기반 결제 핸들러의 서비스 워커에서 PaymentRequestEvent(cf. user interaction task source)를 발생시킵니다. PaymentRequestEvent에는 PaymentRequest에서 온 일부 정보([payment-request]에서 정의됨)와 추가 정보(예: 수취인의 출처 등)가 포함됩니다.
  6. 활성화되면, 웹 기반 결제 핸들러는 결제 요청을 처리하기 위해 필요한 절차를 수행하고, 적절한 결제 응답을 수취인(payee)에게 반환합니다. 사용자와의 상호작용이 필요한 경우 웹 기반 결제 핸들러가 해당 목적으로 창을 열 수 있습니다.
  7. 웹 기반 결제 핸들러가 요청 처리를 완료하면, 사용자 에이전트는 비동기로 응답을 받습니다. 이 응답은 PaymentResponse ([payment-request]의)로 지정됩니다.
참고

하나의 출처(origin)는 둘 이상의 서비스 워커를 통해 결제 앱을 구현할 수 있으므로, 동일한 출처에 여러 웹 기반 결제 핸들러가 등록될 수 있습니다. 어느 핸들러가 호출되는지는 사용자의 선택에 따라 결정됩니다.

2.1 결제 요청 처리

이 섹션은 비규범적입니다.

웹 기반 결제 핸들러는 웹 애플리케이션 기반의 결제 핸들러입니다. 즉, 사용자를 대신하여 결제 요청을 처리할 수 있는 웹 애플리케이션입니다.

웹 기반 결제 핸들러의 동작 로직은 지원하는 결제 방법에 따라 달라집니다. 어떤 결제 방법은 웹 기반 결제 핸들러가 거의 또는 전혀 처리없이, 단순히 결제 카드 정보를 응답으로 반환하기만을 기대합니다. 이 경우, 결제 데이터를 입력으로 사용하여 결제를 처리하는 역할은 수취인 웹사이트에 있습니다.

반대로, 암호화폐 결제나 은행이 시작하는 신용 이체와 같은 일부 결제 방법은, 웹 기반 결제 핸들러가 결제 처리를 직접 시작해야 합니다. 이런 경우 웹 기반 결제 핸들러는 결제 참고 정보, 엔드포인트 URL, 또는 수취인 웹사이트가 결제 결과를 확인하는 데 사용할 수 있는 기타 데이터를 반환합니다 (즉, 직접 결제를 처리하지 않고).

결제 요청을 처리하는 과정에는 다양한 상호작용이 포함될 수 있습니다. 예를 들어, 새 창이나 다른 API(Web Cryptography API 등)를 통한 사용자와의 상호작용, 또는 웹 요청 등으로 외부 서비스·출처와의 상호작용 등이 포함됩니다.

이 명세서는 웹 기반 결제 핸들러가 PaymentRequestEvent를 수락하고 응답을 반환하는 과정에서 발생하는 이런 활동들에 대해 다루지 않습니다. 결제 요청 처리를 위해 웹 기반 결제 핸들러의 설정과 처리에 필요한 모든 활동은, 웹 기반 결제 핸들러의 구현에 맡기며, 예를 들면:

따라서 한 출처(origin)는 생명주기 관리, 보안, 사용자 인증, 사용자 상호작용 등 그 외 다양한 웹 기술에 의존하게 됩니다.

2.2 다른 유형의 결제 앱과의 관계

이 섹션은 비규범적입니다.

이 명세서는 서드파티 모바일 결제 앱이 사용자 에이전트와 독점적 메커니즘을 통해 어떻게 상호작용하는지, 또는 사용자 에이전트 자체가 간단한 결제 앱 기능을 어떻게 제공하는지는 다루지 않습니다.

Different types of payment apps. Web-based Payment Handler API is for Web apps.
그림 1 웹 기반 결제 핸들러 API는 웹 앱이 결제를 처리할 수 있도록 합니다. 다른 유형의 결제 앱은 다른(독점적인) 메커니즘을 사용할 수 있습니다.

3. 등록

웹 기반 결제 핸들러는 즉시(Just-In-Time, JIT) 등록 메커니즘을 통해 사용자 에이전트에 등록됩니다.

3.1 즉시(Just-in-time) 등록

상인이 show() 메서드를 호출할 때 웹 기반 결제 핸들러가 등록되어 있지 않다면, 사용자 에이전트는 거래 중에 이 웹 기반 결제 핸들러를 사용자가 등록하도록 허용할 수 있습니다 ("즉시(Just-in-time)" 등록).

이 섹션의 나머지 내용은 비규범적입니다.

사용자 에이전트는 상인이 요청한 URL 기반 결제 방식 식별자를 통해 찾은 결제 방식 매니페스트에서 웹 기반 결제 핸들러 정보를 도출함으로써 즉시 설치(Just-in-time installation)를 수행할 수 있습니다.

4. 관리

이 섹션에서는 웹 기반 결제 핸들러가 자신의 속성을 관리하기 위해 사용할 수 있는 기능을 설명합니다.

4.1 ServiceWorkerRegistration 인터페이스의 확장

WebIDLpartial interface ServiceWorkerRegistration {
  [SameObject] readonly attribute PaymentManager paymentManager;
};

paymentManager 속성은 웹 기반 결제 핸들러 관리 기능을 제공합니다.

4.2 PaymentManager 인터페이스

WebIDL[SecureContext, Exposed=(Window)]
interface PaymentManager {
  attribute DOMString userHint;
  Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations);
};

PaymentManager웹 기반 결제 핸들러가 지원하는 위임(delegation)을 관리하는 데 사용됩니다.

4.2.1 userHint 속성

웹 기반 결제 핸들러의 이름과 아이콘을 표시할 때, 사용자 에이전트는 사용자 경험을 향상시키기 위해 이 문자열을 사용할 수 있습니다. 예를 들어, "**** 1234"와 같은 사용자 힌트는 특정 카드가 해당 웹 기반 결제 핸들러를 통해 사용 가능함을 사용자에게 상기시켜줄 수 있습니다.

4.2.2 enableDelegations() 메서드

이 메서드는 웹 기반 결제 핸들러가 비동기적으로 지원하는 PaymentDelegation 목록을 선언할 수 있도록 합니다.

4.3 PaymentDelegation enum

WebIDLenum PaymentDelegation {
  "shippingAddress",
  "payerName",
  "payerPhone",
  "payerEmail"
};
"shippingAddress"
웹 기반 결제 핸들러는 필요할 때마다 배송지 주소를 제공합니다.
"payerName"
웹 기반 결제 핸들러는 필요할 때마다 결제자의 이름을 제공합니다.
"payerPhone"
웹 기반 결제 핸들러는 필요할 때마다 결제자의 전화번호를 제공합니다.
"payerEmail"
웹 기반 결제 핸들러는 필요할 때마다 결제자의 이메일을 제공합니다.

5. 결제 가능 여부

웹 기반 결제 핸들러CanMakePaymentEvent를 지원하는 경우, 사용자 에이전트는 사용 가능한 웹 기반 결제 핸들러를 필터링하는 데 이 기능을 활용할 수 있습니다.

구현에서는 개발자가 CanMakePaymentEvent에 응답할 수 있도록 타임아웃을 부과할 수 있습니다. 타임아웃이 만료되면, 구현은 respondWith()false로 호출된 것처럼 동작합니다.

5.1 ServiceWorkerGlobalScope의 확장

WebIDLpartial interface ServiceWorkerGlobalScope {
  attribute EventHandler oncanmakepayment;
};

5.1.1 oncanmakepayment 속성

oncanmakepayment 속성은 해당하는 이벤트 핸들러 이벤트 타입이 "canmakepayment"인 이벤트 핸들러입니다.

5.2 CanMakePaymentEvent

CanMakePaymentEvent는 웹 기반 결제 핸들러가 결제 요청에 응답할 수 있는지를 알리는 신호로 사용됩니다.

WebIDL[Exposed=ServiceWorker]
interface CanMakePaymentEvent : ExtendableEvent {
  constructor(DOMString type);
  undefined respondWith(Promise<boolean> canMakePaymentResponse);
};

5.2.1 respondWith() 메서드

이 메서드는 웹 기반 결제 핸들러가 결제 요청에 응답할 수 있는지를 알리는 신호로 사용됩니다.

5.3 CanMakePaymentEvent 처리

PaymentRequest를 수신하면, 사용자 에이전트는 다음 단계를 MUST 수행합니다:

  1. 사용자 에이전트 설정이 CanMakePaymentEvent 사용을 금지하는 경우(예: 사생활 보호 모드), 이 단계를 종료합니다.
  2. registrationServiceWorkerRegistration으로 둡니다.
  3. registration을 찾을 수 없으면, 이 단계를 종료합니다.
  4. 기능 이벤트 발생 "canmakepayment"를 CanMakePaymentEvent를 사용해 registration에서 수행합니다.

5.4 CanMakePaymentEvent 처리 예시

이 섹션은 비규범적입니다.

이 예시는 CanMakePaymentEvent를 수신하는 서비스 워커를 작성하는 방법을 보여줍니다. CanMakePaymentEvent가 수신되면, 서비스 워커는 항상 true를 반환합니다.

Example 1: Handling the CanMakePaymentEvent
self.addEventListener("canmakepayment", function(e) {
  e.respondWith(new Promise(function(resolve, reject) {
    resolve(true);
  }));
});

5.5 결제 핸들러 필터링

PaymentMethodData결제 방식 식별자로 일치하는 웹 기반 결제 핸들러가 주어지면, 다음 알고리즘은 해당 웹 기반 결제 핸들러를 결제에 사용할 수 있다면 true를 반환합니다:

  1. methodName결제 방식 식별자 문자열로, PaymentMethodData에 지정된 값으로 설정한다.
  2. methodDataPaymentMethodData의 해당 결제 방식에 특화된 데이터로 설정한다.
  3. paymentHandlerOrigin을 웹 기반 결제 핸들러의 ServiceWorkerRegistration scope URL의 origin으로 설정한다.
  4. paymentMethodManifestmethodName에 대해 로드파싱결제 방식 매니페스트로 설정한다.
  5. 만약 methodNameURL 기반 결제 방식 식별자이고, paymentMethodManifest"*" 문자열이 허용 origin에 포함된다면, true를 반환한다.
  6. 그렇지 않고, URL 기반 결제 방식 식별자 methodNameoriginpaymentHandlerOrigin과 같으면, 웹 기반 결제 핸들러에서 CanMakePaymentEvent를 발생시키고 그 결과를 반환한다.
  7. 그 밖에, paymentMethodManifest허용 origin이 순서가 있는 origin 집합이고, 그 집합에 paymentHandlerOrigin이 포함되어 있다면, 웹 기반 결제 핸들러에서 CanMakePaymentEvent를 발생시키고 그 결과를 반환한다.
  8. 그 외의 경우는 false를 반환한다.

6. 호출

사용자가 웹 기반 결제 핸들러를 선택하면, 사용자 에이전트는 PaymentRequestEvent 를 발생시키고, 이어지는 PaymentHandlerResponse 를 이용하여 [payment-request]의 PaymentResponse를 생성합니다.

이슈 117: Abort() 지원을 결제 핸들러에 위임

Payment Request API는 결제 앱에 abort(중단) 관리 책임의 위임을 지원합니다. 웹 기반 결제 핸들러 인터페이스에 paymentRequestAborted 이벤트를 추가하는 제안이 있습니다. 이 이벤트는 결제 요청이 성공적으로 중단(aborted)되었는지 표시하는 불리언 인자를 받는 respondWith 메서드를 가질 예정입니다.

6.1 ServiceWorkerGlobalScope 의 확장

이 명세는 ServiceWorkerGlobalScope 인터페이스를 확장합니다.

WebIDLpartial interface ServiceWorkerGlobalScope {
  attribute EventHandler onpaymentrequest;
};

6.1.1 onpaymentrequest 속성

onpaymentrequest 속성은 이벤트 핸들러이며, 해당 이벤트 핸들러 이벤트 타입PaymentRequestEvent입니다.

6.2 PaymentRequestDetailsUpdate

PaymentRequestDetailsUpdate는 웹 기반 결제 핸들러 내에서 결제 수단, 배송지 주소 또는 배송 옵션을 사용자가 선택함으로써 발생한 수정된 전체 금액(선택적으로 수정자 및 배송 옵션 포함)과 가능한 오류를 포함합니다.

WebIDLdictionary PaymentRequestDetailsUpdate {
  DOMString error;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  sequence<PaymentShippingOption> shippingOptions;
  object paymentMethodErrors;
  AddressErrors shippingAddressErrors;
};

6.2.1 error 멤버

사람이 읽을 수 있는 문자열로, 사용자가 선택한 웹 기반 결제 수단, 배송지 주소 또는 배송 옵션을 사용할 수 없는 이유를 설명합니다.

6.2.2 total 멤버

변경된 결제 수단, 배송 주소 또는 배송 옵션을 기반으로 갱신된 총액입니다. 예를 들어 사용자가 선택한 결제 수단의 청구지 주소 때문에 부가가치세(VAT)가 바뀌거나, 사용자가 선택/제공한 배송 옵션/주소 때문에 배송비가 바뀔 수 있습니다.

6.2.3 modifiers 멤버

변경된 결제 수단, 배송 주소 또는 배송 옵션을 기반으로 갱신된 modifiers입니다. 예를 들어 청구지 또는 배송 주소를 기반으로 전체 합계가 €1.00 증가했다면, 각 modifier에 지정된 합계도 €1.00 증가해야 합니다.

6.2.4 shippingOptions 멤버

변경된 배송 주소를 기반으로 갱신된 shippingOptions입니다. 예를 들어, 사용자 제공 국가에서는 빠른 배송이 더 비싸거나 사용 불가능할 수 있습니다.

6.2.5 paymentMethodErrors 멤버

해당하는 경우, 결제 수단에 대한 검증 오류입니다.

6.2.6 shippingAddressErrors 멤버

해당하는 경우, 배송 주소에 대한 검증 오류입니다.

6.3 PaymentRequestEvent

PaymentRequestEvent는 사용자가 선택한 이후 결제 핸들러에서 사용할 수 있는 데이터와 메서드를 나타냅니다. 사용자 에이전트는 PaymentRequest에서 사용 가능한 데이터의 하위 집합을 결제 핸들러에 전달합니다.

WebIDL[Exposed=ServiceWorker]
interface PaymentRequestEvent : ExtendableEvent {
  constructor(DOMString type, optional PaymentRequestEventInit eventInitDict = {});
  readonly attribute USVString topOrigin;
  readonly attribute USVString paymentRequestOrigin;
  readonly attribute DOMString paymentRequestId;
  readonly attribute FrozenArray<PaymentMethodData> methodData;
  readonly attribute object total;
  readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
  readonly attribute object? paymentOptions;
  readonly attribute FrozenArray<PaymentShippingOption>? shippingOptions;
  Promise<WindowClient?> openWindow(USVString url);
  Promise<PaymentRequestDetailsUpdate?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
  Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(optional AddressInit shippingAddress = {});
  Promise<PaymentRequestDetailsUpdate?> changeShippingOption(DOMString shippingOption);
  undefined respondWith(Promise<PaymentHandlerResponse> handlerResponsePromise);
};

6.3.1 topOrigin 속성

최상위 origin을 나타내는 문자열을 반환합니다. 이는 최상위 수취인 웹 페이지의 origin입니다. 이 속성은 PaymentRequestEvent 처리에 의해 초기화됩니다.

6.3.2 paymentRequestOrigin 속성

PaymentRequest가 초기화된 origin을 나타내는 문자열을 반환합니다. PaymentRequesttopOrigin에서 초기화된 경우, 두 속성의 값은 같고, 그렇지 않으면 서로 다릅니다. 예를 들어 PaymentRequesttopOrigin이 아닌 origin의 iframe 내에서 초기화된 경우, 이 속성 값은 해당 iframe의 origin입니다. 이 속성은 PaymentRequestEvent 처리에 의해 초기화됩니다.

6.3.3 paymentRequestId 속성

가져올 때, paymentRequestId 속성은 이 PaymentRequestEvent에 대응하는 PaymentRequest[[details]].id를 반환합니다.

6.3.4 methodData 속성

이 속성에는 웹 사이트가 수락하는 결제 수단 식별자를 포함하는 PaymentMethodData 딕셔너리들과, 관련된 결제 수단별 데이터가 포함됩니다. 이는 아래에 정의된 MethodData 채우기 알고리즘을 사용하여 PaymentRequest로부터 채워집니다.

6.3.5 total 속성

이 속성은 결제를 위해 요청되는 총액을 나타냅니다. 이는 [payment-request]에 정의된 PaymentCurrencyAmount 딕셔너리 타입이며, 해당 PaymentRequest 객체가 생성될 때 제공된 total 필드의 복사본으로 초기화됩니다.

6.3.6 modifiers 속성

PaymentDetailsModifier 딕셔너리의 시퀀스는 특정 결제 수단 식별자에 대한 modifier들을 포함합니다(예: 결제 수단에 따라 결제 금액이나 통화가 달라지는 경우). 이는 아래에 정의된 Modifiers 채우기 알고리즘을 사용하여 PaymentRequest로부터 채워집니다.

6.3.7 paymentOptions 속성

PaymentOptions의 값입니다. 배송 주소 및/또는 지불자의 연락처 정보의 일부가 요청된 경우에만 사용할 수 있습니다. 이 값은 PaymentRequest에서 가져옵니다.

6.3.8 shippingOptions 속성

해당 PaymentRequestPaymentDetailsInit 딕셔너리에 있는 ShippingOptions의 값입니다. (PaymentDetailsInitPaymentDetailsBase로부터 ShippingOptions를 상속합니다). 배송 주소가 요청된 경우에만 사용할 수 있습니다.

6.3.9 openWindow() 메서드

이 메서드는 웹 기반 결제 핸들러가 사용자에게 창을 보여주기 위해 사용됩니다. 호출 시 윈도우 열기 알고리즘을 실행합니다.

6.3.10 changePaymentMethod() 메서드

이 메서드는 웹 기반 결제 핸들러가 결제 방법 세부 정보(예: 청구지 주소)를 받아 업데이트된 전체 금액을 가져오기 위해 사용됩니다. 호출 시 결제 방법 변경 알고리즘을 실행합니다.

6.3.11 changeShippingAddress() 메서드

이 메서드는 웹 기반 결제 핸들러가 shippingAddress(배송지 주소)를 받아 업데이트된 결제 세부 정보를 가져오기 위해 사용됩니다. 호출 시 결제 세부 정보 변경 알고리즘을 실행합니다.

6.3.12 changeShippingOption() 메서드

이 메서드는 웹 기반 결제 핸들러가 shippingOption(배송 옵션) 식별자를 받아 업데이트된 결제 세부 정보를 가져오기 위해 사용됩니다. 호출 시 결제 세부 정보 변경 알고리즘을 실행합니다.

6.3.13 respondWith() 메서드

이 메서드는 웹 기반 결제 핸들러가 결제가 성공적으로 완료되었을 때 PaymentHandlerResponse를 제공하기 위해 사용됩니다. 호출 시 결제 요청 응답 알고리즘eventhandlerResponsePromise를 인자로 하여 실행합니다.

Issue 123: 사용자 데이터를 결제 앱과 공유할까요?

사용자 에이전트에 저장된 사용자 데이터를, 사용자의 명시적 동의를 받아 결제 앱이 수신해야 할까요? 결제 앱은 설치 시점 또는 최초 호출 시점에 권한을 요청할 수 있습니다.

6.3.14 PaymentRequestEventInit 딕셔너리

WebIDLdictionary PaymentRequestEventInit : ExtendableEventInit {
  USVString topOrigin;
  USVString paymentRequestOrigin;
  DOMString paymentRequestId;
  sequence<PaymentMethodData> methodData;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  PaymentOptions paymentOptions;
  sequence<PaymentShippingOption> shippingOptions;
};

topOrigin, paymentRequestOrigin, paymentRequestId, methodData, total, modifiers, paymentOptions, 그리고 shippingOptions 멤버들은 PaymentRequestEvent에 대해 정의된 것들과 동일한 정의를 공유합니다.

6.3.15 MethodData 채우기 알고리즘

methodData의 값을 초기화하기 위해, 사용자 에이전트는 다음 단계(또는 그에 상응하는 단계)를 MUST 수행합니다:

  1. registeredMethods를 호출된 웹 기반 결제 핸들러의 등록된 결제 방식 식별자들의 집합으로 설정한다.
  2. 새로운 비어 있는 Sequence를 생성합니다.
  3. dataList를 새로 생성한 Sequence로 설정합니다.
  4. 해당 결제 요청의 PaymentRequest@[[methodData]]의 각 항목에 대해 다음 단계를 수행합니다:
    1. inData를 현재 고려 중인 항목으로 설정합니다.
    2. commonMethodsinData.supportedMethodsregisteredMethods의 교집합으로 설정합니다.
    3. commonMethods가 비어 있으면, 나머지 하위 단계를 건너뛰고 다음 항목(있는 경우)으로 넘어갑니다.
    4. 새로운 PaymentMethodData 객체를 생성합니다.
    5. outData를 새로 생성한 PaymentMethodData로 설정합니다.
    6. outData.supportedMethodscommonMethods의 구성원을 포함하는 리스트로 설정합니다.
    7. outData.data를 inData.data의 복사본으로 설정합니다.
    8. outDatadataList에 추가합니다.
  5. methodDatadataList로 설정합니다.

6.3.16 Modifiers 채우기 알고리즘

modifiers의 값을 초기화하기 위해, 사용자 에이전트는 다음 단계(또는 그에 상응하는 단계)를 MUST 수행합니다:

  1. registeredMethods를 호출된 웹 기반 결제 핸들러의 등록된 결제 방식 식별자들의 집합으로 설정한다.
  2. 새로운 비어 있는 Sequence를 생성합니다.
  3. modifierList를 새로 생성한 Sequence로 설정합니다.
  4. 해당 결제 요청의 PaymentRequest@[[paymentDetails]].modifiers의 각 항목에 대해 다음 단계를 수행합니다:
    1. inModifier를 현재 고려 중인 항목으로 설정합니다.
    2. commonMethodsinModifier.supportedMethodsregisteredMethods의 교집합으로 설정합니다.
    3. commonMethods가 비어 있으면, 나머지 하위 단계를 건너뛰고 다음 항목(있는 경우)으로 넘어갑니다.
    4. 새로운 PaymentDetailsModifier 객체를 생성합니다.
    5. outModifier를 새로 생성한 PaymentDetailsModifier로 설정합니다.
    6. outModifier.supportedMethodscommonMethods의 구성원을 포함하는 리스트로 설정합니다.
    7. outModifier.totalinModifier.total의 복사본으로 설정합니다.
    8. outModifiermodifierList에 추가합니다.
  5. modifiersmodifierList로 설정합니다.

6.4 내부 슬롯

PaymentRequestEvent의 인스턴스는 다음 표의 내부 슬롯들과 함께 생성됩니다:

내부 슬롯 기본값 설명 (비규범적)
[[windowClient]] null 현재 활성화된 WindowClient입니다. 웹 기반 결제 핸들러가 현재 사용자에게 창을 표시하고 있을 때 설정됩니다. 그렇지 않으면 null입니다.
[[respondWithCalled]] false YAHO

6.5 PaymentRequestEvent 처리

PaymentRequestPaymentRequest.show()를 통해 수신하고, 이어서 사용자가 웹 기반 결제 핸들러를 선택한 경우, 사용자 에이전트반드시 다음 절차를 진행해야 합니다:

  1. registration을 사용자가 선택한 웹 기반 결제 핸들러에 해당하는 ServiceWorkerRegistration 으로 설정한다.
  2. registration이 존재하지 않을 경우, PromisePaymentRequest.show()에서 생성되었던 "InvalidStateError" DOMException로 거부하고 이 과정을 종료한다.
  3. 기능성 이벤트 실행(Fire Functional Event) "paymentrequest"를 registration에서 PaymentRequestEvent를 사용하여 다음 속성이 포함되도록 실행한다:

    topOrigin
    최상위 결제(지불) 웹 페이지의 origin의 직렬화 값.
    paymentRequestOrigin
    PaymentRequest가 초기화된 컨텍스트의 origin의 직렬화 값.
    methodData
    MethodData 채우기 알고리즘의 실행 결과.
    modifiers
    Modifiers 채우기 알고리즘의 실행 결과.
    total
    해당 PaymentRequestPaymentDetailsInit의 total 필드 복사본.
    paymentRequestId
    PaymentRequest에서 \[\[details\]\].id 값.
    paymentOptions
    해당 PaymentRequest 생성자에 전달된 paymentOptions 딕셔너리의 복사본.
    shippingOptions
    해당 PaymentRequestPaymentDetailsInit의 shippingOptions 필드 복사본.

    그런 다음 dispatchedEvent와 함께 다음 단계를 병렬로 수행한다:

    1. dispatchedEvent extend lifetime promise의 모든 Promise가 resolve될 때까지 대기한다.
    2. 웹 기반 결제 핸들러PaymentHandlerResponse를 제공하지 않았다면, PromisePaymentRequest.show()에서 생성되었던 "OperationError" DOMException로 거부한다.

7. 윈도우

호출된 웹 기반 결제 핸들러는 자신에 대한 정보를 표시하거나 사용자 입력을 요청할 필요가 있을 수도, 없을 수도 있습니다. 웹 기반 결제 핸들러가 정보를 표시해야 할 잠재적인 예시는 다음과 같습니다:

시각적 표시와 사용자 상호작용이 필요한 웹 기반 결제 핸들러는 openWindow()를 호출해 사용자에게 페이지를 띄울 수 있습니다.

참고

사용자 에이전트는 이 메서드가 PaymentRequestEvent 와 연관됨을 알고 있으므로, 마땅히 플로우와 일관되고 사용자에게 혼란을 주지 않는 방식으로 창을 렌더링해야 합니다. 결과로 생성되는 window client는 PaymentRequest를 시작한 탭/창에 바인딩됩니다. 단일 웹 기반 결제 핸들러는 본 메서드를 사용해 둘 이상의 클라이언트 창을 여는 것이 허용되지 않아야 합니다.

7.1 창 열기 알고리즘

Issue 115: The Open Window Algorithm

이 알고리즘은 Service Workers 명세의 Open Window Algorithm 과 유사합니다.

Issue 115: Open Window Algorithm

우리는 단계들을 복사하는 대신 Service Workers 명세를 참조해야 할까요?

  1. event를 이 PaymentRequestEvent로 설정한다.
  2. eventisTrusted 속성이 false라면, "InvalidStateError" DOMException으로 reject된 Promise를 반환한다.
  3. request를 이 PaymentRequest를 트리거한 PaymentRequestEvent로 설정한다.
  4. urlurl 인자를 파싱한 결과로 설정한다.
  5. url 파싱 시 예외가 발생하면, 그 예외로 reject된 Promise를 반환한다.
  6. urlabout:blank 이라면, PromiseTypeError로 reject해서 반환한다.
  7. url의 origin이 웹 기반 결제 핸들러와 연결된 service worker의 origin과 동일하지 않다면, null로 resolve된 Promise를 반환한다.
  8. promise를 새 Promise로 설정한다.
  9. promise를 반환하고, 남은 단계는 병렬로 수행한다:
  10. event.[[windowClient]]가 null이 아니라면:
    1. event.[[windowClient]].visibilityState 가 "unloaded"가 아니면, promise를 "InvalidStateError" DOMException으로 reject하고, 이 단계를 중단한다.
  11. newContext를 새 최상위 브라우징 컨텍스트로 설정한다.
  12. 예외 및 replacement 사용을 활성화한 상태로 NavigatenewContexturl에 실행한다.
  13. navigation 도중 예외가 던져지면 promise를 그 예외로 reject하고, 이 단계를 중단한다.
  14. newContext의 origin이 웹 기반 결제 핸들러와 연관된 service worker client origin과 같지 않다면:
    1. promise를 null로 resolve한다.
    2. 이 단계를 중단한다.
  15. clientnewContext를 인자로 하여 create window client 알고리즘을 실행한 결과로 설정한다.
  16. event.[[windowClient]]client를 할당한다.
  17. promiseclient로 resolve한다.

7.2 PaymentRequestEvent 처리 예시

이 섹션은 비규범적입니다.

이 예시는 PaymentRequestEvent를 수신하는 서비스 워커를 작성하는 방법을 보여줍니다. PaymentRequestEvent가 수신되면, 서비스 워커는 사용자와 상호작용하기 위해 창을 엽니다.

Example 2: PaymentRequestEvent 처리
async function getPaymentResponseFromWindow() {
  return new Promise((resolve, reject) => {
    self.addEventListener("message", listener = e => {
      self.removeEventListener("message", listener);
      if (!e.data || !e.data.methodName) {
        reject();
        return;
      }
      resolve(e.data);
    });
  });
}

self.addEventListener("paymentrequest", e => {
  e.respondWith((async() => {
    // Open a new window for providing payment UI to user.
    const windowClient = await e.openWindow("payment_ui.html");

    // Send data to the opened window.
    windowClient.postMessage({
      total: e.total,
      modifiers: e.modifiers
    });

    // Wait for a payment response from the opened window.
    return await getPaymentResponseFromWindow();
  })());
});

위에서 설명한 단순한 방식을 사용하면, 웹 기반 결제 핸들러 창에 로드되는 가장 기본적인 HTML 페이지는 다음과 같을 수 있습니다:

Example 3: 간단한 결제 핸들러 창
<form id="form">
<table>
  <tr><th>Cardholder Name:</th><td><input name="cardholderName"></td></tr>
  <tr><th>Card Number:</th><td><input name="cardNumber"></td></tr>
  <tr><th>Expiration Month:</th><td><input name="expiryMonth"></td></tr>
  <tr><th>Expiration Year:</th><td><input name="expiryYear"></td></tr>
  <tr><th>Security Code:</th><td><input name="cardSecurityCode"></td></tr>
  <tr><th></th><td><input type="submit" value="Pay"></td></tr>
</table>
</form>

<script>
navigator.serviceWorker.addEventListener("message", e => {
  /* Note: message sent from payment app is available in e.data */
});

document.getElementById("form").addEventListener("submit", e => {
  const details = {};
  ["cardholderName", "cardNumber", "expiryMonth", "expiryYear", "cardSecurityCode"]
  .forEach(field => {
    details[field] = form.elements[field].value;
  });

  const paymentAppResponse = {
    methodName: "https://example.com/pay",
    details
  };

  navigator.serviceWorker.controller.postMessage(paymentAppResponse);
  window.close();
});
</script>

8. 응답

8.1 PaymentHandlerResponse 딕셔너리

PaymentHandlerResponse는 다음 딕셔너리를 사용하여 전달됩니다:
WebIDLdictionary PaymentHandlerResponse {
DOMString methodName;
object details;
DOMString? payerName;
DOMString? payerEmail;
DOMString? payerPhone;
AddressInit shippingAddress;
DOMString? shippingOption;
};

8.1.1 methodName 속성

사용자가 거래를 완료하기 위해 선택한 결제 수단결제 수단 식별자입니다.

8.1.2 details 속성

JSON으로 직렬화 가능한 객체로, 가맹점이 거래를 처리하고 자금 이체 성공 여부를 결정하는 데 사용하는 결제 방식별 메시지를 제공합니다.

사용자 에이전트는 해당 respondWith 함수에 제공된 Promise가 성공적으로 resolve되는 것을 통해 웹 기반 결제 핸들러로부터 응답을 받습니다. 애플리케이션은 이 Promise를 결제 응답을 담은 PaymentHandlerResponse 인스턴스로 resolve해야 합니다. 사용자가 결제를 취소하거나 오류가 발생한 경우, 애플리케이션은 Promise를 reject하여 실패를 알릴 수 있습니다.

Promise가 reject될 경우, 사용자 에이전트는 반드시 결제 앱 오류 처리 알고리즘을 실행해야 합니다. 이 알고리즘의 정확한 세부 사항은 구현자에게 맡겨집니다. 허용되는 동작에는 다음이 포함되지만 이에 국한되지 않습니다:

  • 동일한 웹 기반 결제 핸들러 또는 다른 결제 핸들러로 사용자가 다시 시도할 수 있도록 허용
  • PaymentRequest.show() 에 의해 생성된 Promise를 reject

8.1.3 payerName 속성

사용자가 제공한 지불자 이름입니다.

8.1.4 payerEmail 속성

사용자가 제공한 지불자 이메일입니다.

8.1.5 payerPhone 속성

사용자가 제공한 지불자 전화번호입니다.

8.1.6 shippingAddress 속성

사용자가 제공한 배송 주소입니다.

8.1.7 shippingOption 속성

사용자가 선택한 배송 옵션의 식별자입니다.

8.2 결제 수단 변경 알고리즘

이 알고리즘이 methodNamemethodDetails 매개변수와 함께 호출되면, 사용자 에이전트는 다음 단계를 MUST 수행합니다:

  1. payment method changed 알고리즘을, 주어진 methodNamemethodDetails 매개변수로 구성한 PaymentMethodChangeEvent event와 함께 실행한다.
  2. eventupdateWith(detailsPromise)가 실행되지 않았다면, null을 반환한다.
  3. eventupdateWith(detailsPromise)가 예외를 던지면, 그 오류를 재던진다.
  4. 선택적으로, eventupdateWith(detailsPromise)가 타임아웃되면, "InvalidStateError" DOMException을 던진다.
  5. eventupdateWith(detailsPromise)detailsPromise로부터 PaymentRequestDetailsUpdate를 구성하여 반환한다.

8.3 결제 상세 변경 알고리즘

이 알고리즘이 shippingAddress 또는 shippingOption과 함께 호출되면, 사용자 에이전트는 다음 단계를 MUST 수행합니다:

  1. 갱신된 상세(shippingAddress 또는 shippingOption)로 구성한 PaymentRequestUpdateEvent event와 함께 PaymentRequest updated 알고리즘을 실행한다.
  2. eventupdateWith(detailsPromise)가 실행되지 않았다면, null을 반환한다.
  3. eventupdateWith(detailsPromise)가 예외를 던지면, 그 오류를 재던진다.
  4. 선택적으로, eventupdateWith(detailsPromise)가 타임아웃되면, "InvalidStateError" DOMException을 던진다.
  5. eventupdateWith(detailsPromise)detailsPromise로부터 PaymentRequestDetailsUpdate를 구성하여 반환한다.

8.4 PaymentRequest에 응답하는 알고리즘

이 알고리즘이 eventhandlerResponsePromise 매개변수와 함께 호출되면, 사용자 에이전트는 다음 단계를 MUST 수행합니다:

  1. eventisTrusted가 false이면, "InvalidStateError" DOMException을 던지고 이 단계를 중단한다.
  2. eventdispatch flag가 설정되어 있지 않다면, "InvalidStateError" DOMException을 던지고 이 단계를 중단한다.
  3. event.[[respondWithCalled]]가 true이면, "InvalidStateError" DOMException을 던지고 이 단계를 중단한다.
  4. event.[[respondWithCalled]]를 true로 설정한다.
  5. eventstop propagation flageventstop immediate propagation flag를 설정한다.
  6. handlerResponsePromiseeventextend lifetime promises에 추가한다.
  7. eventpending promises count를 1 증가시킨다.
  8. 거부될 때 handlerResponsePromise에 대해:
    1. 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
  9. 이행될 때 handlerResponsePromise에 대해:
    1. handlerResponsevalueIDL 값으로 변환하여 얻은 PaymentHandlerResponse로 둔다. 변환이 예외를 던지면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
    2. handlerResponse의 모든 필수 멤버가 존재하며 올바르게 형식화되었는지 검증한다.
      1. handlerResponsemethodName이 없거나 eventmethodData의 값들 중 하나로 설정되어 있지 않으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      2. handlerResponsedetails가 없거나 JSON으로 직렬화 가능하지 않으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      3. shippingRequired를 관련 PaymentRequest의 requestShipping 값으로 둔다. shippingRequired이고 handlerResponseshippingAddress가 없으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      4. shippingRequired이고 handlerResponseshippingOption이 없거나 eventshippingOptions의 배송 옵션 식별자들 중 하나로 설정되어 있지 않으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      5. payerNameRequired를 관련 PaymentRequest의 requestPayerName 값으로 둔다. payerNameRequired이고 handlerResponsepayerName이 없으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      6. payerEmailRequired를 관련 PaymentRequest의 requestPayerEmail 값으로 둔다. payerEmailRequired이고 handlerResponsepayerEmail이 없으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      7. payerPhoneRequired를 관련 PaymentRequest의 requestPayerPhone 값으로 둔다. payerPhoneRequired이고 handlerResponsepayerPhone이 없으면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
    3. handlerResponse의 필수 멤버들을 직렬화한다( methodNamedetails는 항상 필수이며, shippingRequired가 true이면 shippingAddressshippingOption이 필수이고, payerNameRequired, payerEmailRequired, payerPhoneRequired가 각각 true이면 payerName, payerEmail, payerPhone이 필수임):
      1. handlerResponse의 각 member에 대해, serializeMemberStructuredSerialize handlerResponse.member에 적용한 결과로 둔다. 예외가 있으면 재던진다.
    4. 사용자 에이전트는 MUST [payment-request]에 정의된 사용자가 결제 요청을 수락하는 알고리즘을 실행하되, 단계 9-15를 다음 단계 또는 그에 상응하는 단계로 대체한다.
      1. 직렬화된 멤버들을 역직렬화한다:
        1. serializeMember에 대해, memberStructuredDeserializeserializeMember에 적용한 결과로 둔다. 예외가 있으면 재던진다.
      2. 위 단계에서 어떤 예외라도 발생하면, 결제 앱 실패 알고리즘을 실행하고 이 단계를 종료한다.
      3. methodName을 관련 PaymentRequest의 responsemethodName에 할당한다.
      4. details를 관련 PaymentRequest의 responsedetails에 할당한다.
      5. shippingRequired이면, 관련 PaymentReqeust의 shippingAddress 속성을 shippingAddress로 설정하고, 그렇지 않으면 null로 설정한다.
      6. shippingRequired이면, 관련 PaymentReqeust의 shippingOption 속성을 shippingOption으로 설정하고, 그렇지 않으면 null로 설정한다.
      7. payerNameRequired이면, 관련 PaymentReqeust의 payerName 속성을 payerName으로 설정하고, 그렇지 않으면 null로 설정한다.
      8. payerEmailRequired이면, 관련 PaymentReqeust의 payerEmail 속성을 payerEmail로 설정하고, 그렇지 않으면 null로 설정한다.
      9. payerPhoneRequired이면, 관련 PaymentReqeust의 payerPhone 속성을 payerPhone으로 설정하고, 그렇지 않으면 null로 설정한다.
  10. 이행 또는 거부 시, handlerResponsePromise에 대해 다음 단계를 수행하도록 마이크로태스크를 큐에 넣는다:
    1. eventpending promises count를 1 감소시킨다.
    2. registrationthis관련 전역 객체와 연결된 service workercontaining service worker registration으로 둔다.
    3. registration이 null이 아니면, Try Activateregistration으로 호출한다.

다음 예시는 결제 요청에 응답하는 방법을 보여줍니다:

Example 4: 결제 응답 보내기
paymentRequestEvent.respondWith(new Promise(function(accept,reject) {
  /* ... processing may occur here ... */
  accept({
    methodName: "https://example.com/pay",
    details: {
      cardHolderName:   "John Smith",
      cardNumber:       "1232343451234",
      expiryMonth:      "12",
      expiryYear :      "2020",
      cardSecurityCode: "123"
     },
    shippingAddress: {
      addressLine: [
        "1875 Explorer St #1000",
      ],
      city: "Reston",
      country: "US",
      dependentLocality: "",
      organization: "",
      phone: "+15555555555",
      postalCode: "20190",
      recipient: "John Smith",
      region: "VA",
      sortingCode: ""
    },
    shippingOption: "express",
    payerEmail: "john.smith@gmail.com",
  });
}));
참고

[payment-request]는 생태계의 당사자(결제 앱 제공자 및 수취인 포함)가 네트워크 또는 기타 오류 이후에 정합을 위해 사용할 수 있는 ID를 정의합니다.

9. 보안 및 개인정보 고려사항

9.1 주소

Web Payments 워킹 그룹은 개인정보 보호 이슈로 인해 Payment Request API의 원래 버전에서 배송지와 청구지 주소 지원을 제거했습니다. 자세한 내용은 issue 842를 참조하십시오. 여전히 이 기능을 지원하는 구현을 위한 문서를 제공하기 위해, 워킹 그룹은 개인정보 이슈에 대응할 것을 전제로 이 기능을 복구하고 있습니다. 이 과정에서 워킹 그룹은 다른 API(예: Content Picker API)의 발전을 바탕으로 Payment Request API에 변경을 가할 수도 있습니다.

9.2 사용자 환경에 관한 정보

9.5 교차 출처 데이터 공유에 대한 사용자 인식

9.6 안전한 통신

9.7 승인된 결제 앱

9.8 지원되는 출처

9.9 데이터 검증

9.10 사생활 보호 모드(Private Browsing Mode)

10. 결제 핸들러 표시 고려사항

이 섹션은 비규범적입니다.

웹 기반 결제 핸들러의 순서를 정할 때, 사용자 에이전트는 다른 우선순위보다 사용자의 선호를 우선적으로 존중해야 합니다. 사용자 에이전트는 origin별 또는 전체 origin에 대해 선호하는 웹 기반 결제 핸들러의 표시 순서를 설정 등, 수동 설정 옵션을 허용해야 합니다.

사용자 경험에 관한 세부사항은 구현자에게 맡깁니다.

11. 종속성

이 명세는 여러 다른 기반 명세에 의존합니다.

Payment Request API
용어 payment method, PaymentRequest, PaymentResponse, supportedMethods, PaymentCurrencyAmount, paymentDetailsModifier, paymentDetailsInit, paymentDetailsBase, PaymentMethodData, PaymentOptions, PaymentShippingOption, AddressInit, AddressErrors, PaymentMethodChangeEvent, PaymentRequestUpdateEvent, ID, canMakePayment(), show(), updateWith(detailsPromise), user accepts the payment request algorithm, payment method changed algorithm, PaymentRequest updated algorithm, 그리고 JSON-serializable은 Payment Request API 명세 [payment-request]에 정의되어 있습니다.
ECMAScript
용어 internal slotJSON.stringify 는 [ECMASCRIPT]에 의해 정의됩니다.
Payment Method Manifest
용어 payment method manifest, ingest payment method manifest, parsed payment method manifest, 그리고 supported origins는 Payment Method Manifest 명세 [payment-method-manifest]에 정의되어 있습니다.
Service Workers
용어 service worker, service worker registration, service worker client, ServiceWorkerRegistration, ServiceWorkerGlobalScope, fire functional event, extend lifetime promises,pending promises count, containing service worker registration, Try Clear Registration, Try Activate, ExtendableEvent, ExtendableEventInit, 그리고 scope URL 은 [SERVICE-WORKERS]에 정의되어 있습니다.

12. 적합성

비규범적으로 표시된 섹션들뿐 아니라, 이 명세의 모든 저작 가이드라인, 다이어그램, 예시, 그리고 주석은 비규범적입니다. 그 외의 모든 내용은 규범적입니다.

본 문서에서 MAY, MUST, SHOULD, SHOULD NOT과 같은 핵심 용어는 BCP 14 [RFC2119] [RFC8174] 에서 설명된 대로, 그리고 여기에서처럼 전부 대문자로 나타날 때에만 해당 의미로 해석되어야 합니다.

이 명세에 대한 적합성을 주장할 수 있는 제품 클래스는 단 하나입니다: 사용자 에이전트.

사용자 에이전트는 이 명세에 제시된 알고리즘과 구별할 수 없는 동일한 결과를 산출하는 한, 어떤 방식으로든 이 명세의 알고리즘을 구현할 MAY 있습니다.

사용자 에이전트는 서비스 거부 공격을 방지하거나, 메모리 부족을 방지하거나, 플랫폼 고유의 한계를 우회하기 위해, 원래는 제한되지 않은 입력에 대해 구현별 한계를 부과할 MAY 있습니다. 입력이 구현별 한계를 초과하는 경우, 사용자 에이전트는 MUST 예외를 던지거나, 프로미스의 문맥에서는 TypeError로 거부하면서, 특정 입력이 구현별 한계를 어떻게 초과했는지 개발자에게 선택적으로 알릴 수 있습니다.

A. IDL 색인

WebIDLpartial interface ServiceWorkerRegistration {
  [SameObject] readonly attribute PaymentManager paymentManager;
};

[SecureContext, Exposed=(Window)]
interface PaymentManager {
  attribute DOMString userHint;
  Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations);
};

enum PaymentDelegation {
  "shippingAddress",
  "payerName",
  "payerPhone",
  "payerEmail"
};

partial interface ServiceWorkerGlobalScope {
  attribute EventHandler oncanmakepayment;
};

[Exposed=ServiceWorker]
interface CanMakePaymentEvent : ExtendableEvent {
  constructor(DOMString type);
  undefined respondWith(Promise<boolean> canMakePaymentResponse);
};

partial interface ServiceWorkerGlobalScope {
  attribute EventHandler onpaymentrequest;
};

dictionary PaymentRequestDetailsUpdate {
  DOMString error;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  sequence<PaymentShippingOption> shippingOptions;
  object paymentMethodErrors;
  AddressErrors shippingAddressErrors;
};

[Exposed=ServiceWorker]
interface PaymentRequestEvent : ExtendableEvent {
  constructor(DOMString type, optional PaymentRequestEventInit eventInitDict = {});
  readonly attribute USVString topOrigin;
  readonly attribute USVString paymentRequestOrigin;
  readonly attribute DOMString paymentRequestId;
  readonly attribute FrozenArray<PaymentMethodData> methodData;
  readonly attribute object total;
  readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
  readonly attribute object? paymentOptions;
  readonly attribute FrozenArray<PaymentShippingOption>? shippingOptions;
  Promise<WindowClient?> openWindow(USVString url);
  Promise<PaymentRequestDetailsUpdate?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
  Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(optional AddressInit shippingAddress = {});
  Promise<PaymentRequestDetailsUpdate?> changeShippingOption(DOMString shippingOption);
  undefined respondWith(Promise<PaymentHandlerResponse> handlerResponsePromise);
};

dictionary PaymentRequestEventInit : ExtendableEventInit {
  USVString topOrigin;
  USVString paymentRequestOrigin;
  DOMString paymentRequestId;
  sequence<PaymentMethodData> methodData;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  PaymentOptions paymentOptions;
  sequence<PaymentShippingOption> shippingOptions;
};

dictionary PaymentHandlerResponse {
DOMString methodName;
object details;
DOMString? payerName;
DOMString? payerEmail;
DOMString? payerPhone;
AddressInit shippingAddress;
DOMString? shippingOption;
};

B. 참고문헌

B.1 규범적 참조

[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/multipage/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[payment-method-id]
Payment Method Identifiers. Marcos Caceres. W3C. 8 September 2022. W3C Recommendation. URL: https://www.w3.org/TR/payment-method-id/
[payment-method-manifest]
Payment Method Manifest. Dapeng(Max) Liu; Domenic Denicola; Zach Koch. W3C. 12 December 2017. FPWD. URL: https://www.w3.org/TR/payment-method-manifest/
[payment-request]
Payment Request API. Marcos Caceres; Ian Jacobs; Stephen McGruer. W3C. 27 January 2026. CRD. URL: https://www.w3.org/TR/payment-request/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[SERVICE-WORKERS]
Service Workers Nightly. Monica CHINTALA; Yoshisato Yanagisawa. W3C. 26 January 2026. CRD. URL: https://www.w3.org/TR/service-workers/
[URL]
URL Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

B.2 참고 참조

[WebCryptoAPI]
Web Cryptography API. Mark Watson. W3C. 26 January 2017. W3C Recommendation. URL: https://www.w3.org/TR/WebCryptoAPI/