Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 명세는 판매자(즉, 물리적 또는 디지털 상품을 판매하는 웹사이트)가 최소한의 통합으로 하나 이상의 결제 수단을 활용할 수 있도록 API를 표준화합니다. 사용자 에이전트(예: 브라우저)는 판매자와 사용자 간의 결제 흐름을 지원합니다.
이 섹션은 이 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 발행 문서 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.
2022년 9월, 웹 결제 작업 그룹은 결제 요청 권고안을 발표했습니다. 개인정보 보호 및 국제화 검토 이후, 권고안은 청구 및 배송 주소와 관련된 기능을 제외했습니다. 그러나 구현은 해당 기능을 상호 운용 가능하게 계속 지원해 왔으며, 작업 그룹은 명세를 구현과 다시 조정하고 관련 문제에 대해 커뮤니티와 다시 협력하기로 결정했습니다.
이 문서는 원래 권고안 텍스트를 기반으로 하는 후보 권고안 스냅샷입니다. 이후의 후보 권고안 초안은 주소 기능과 권고안 발표 이후에 이루어진 소수의 다른 변경 사항을 추가할 예정입니다.
주소 지원을 다시 추가하는 과정의 일환으로, 이 명세는 이제 연락처 선택기 API에서 정의된 주소 구성 요소를 참조하며, 더 이상 자체적으로 해당 구성 요소를 정의하지 않습니다. 사실, 연락처 선택기 API는 결제 요청 API에서 발견된 원래 정의에서 파생되었으며, 주소가 결제를 넘어 웹에서 유용하기 때문에 명세에서 분리되었습니다.
작업 그룹은 명세를 제안된 권고안 상태로 발전시키기 전에 논의를 진행하고 일반적인 검토 과정을 따를 계획입니다.
작업 그룹은 구현 보고서를 제작하여 구현 경험을 입증할 것입니다. 이 보고서는 테스트 스위트의 각 필수 테스트를 두 개 이상의 독립적인 구현이 통과했음을 보여줄 것입니다(즉, 각 테스트는 명세의 MUST 요구 사항에 해당합니다).
이 문서는 웹 결제 작업 그룹에서 권고안 트랙을 사용하여 후보 권고안 초안으로 발행한 문서입니다.
후보 권고안으로 발행되었다고 해서 W3C 및 회원사들의 승인을 의미하지는 않습니다. 후보 권고안 초안은 작업 그룹이 이후의 후보 권고안 스냅샷에 포함할 예정인 이전 후보 권고안에서의 변경 사항을 통합합니다.
이 문서는 초안 문서로, 언제든지 업데이트되거나, 대체되거나, 폐기될 수 있습니다. 작업 중인 문서로서 이 문서를 인용하는 것은 적절하지 않습니다. 이 명세의 향후 업데이트는 새로운 기능을 통합할 수 있습니다.
이 문서는 W3C 특허 정책 하에 운영되는 그룹에서 작성되었습니다. W3C는 해당 그룹의 산출물과 관련된 모든 특허 공개 목록을 유지하고 있으며, 그 페이지에는 특허를 공개하는 방법에 대한 지침도 포함되어 있습니다. 특정 특허가 핵심 청구 항목을 포함한다고 믿는 개인은 W3C 특허 정책 6항에 따라 정보를 공개해야 합니다.
이 문서는 2023년 11월 3일 W3C 프로세스 문서의 적용을 받습니다.
이 섹션은 비규범적입니다.
이 명세는 사용자 에이전트 (예: 브라우저)가 거래에서 세 당사자 간의 중개 역할을 할 수 있도록 하는 API를 설명합니다:
결제 방식은 다음을 정의합니다:
PaymentMethodData
의 data
멤버로 받을 것으로 예상되는 IDL 유형. 특정 결제 방식에 대해
지정되지 않은 경우, IDL로 변환되지 않으며 결제 방식은
data
를 JSON으로 받게 됩니다.
data
멤버를 해당 결제 방식의 추가 데이터 유형으로 변환한 후 검증하는 알고리즘 단계. 특정 결제 방식에 대해 지정되지 않은 경우,
검증은 수행되지 않습니다.
주어진 결제 방식의 결제 요청을 충족하는 방법의 세부 사항은 결제 핸들러의 구현 세부 사항으로, 결제를 처리하는 애플리케이션 또는 서비스입니다. 구체적으로, 결제 핸들러는 다음을 정의합니다:
사용자가 결제 방식이나 금융 수단(예: 직불카드에서 신용카드로)을 변경하여 사전(dictionary) 또는 object
또는 null을 반환하는 경우를 처리하는
방법을 설명하는 단계.
이 API는 또한 웹사이트가 보다 안전한 결제 체계(예: 토큰화 및 시스템 수준 인증)를 활용할 수 있도록 하여 표준 자바스크립트 라이브러리로는 불가능한 기능을 제공합니다. 이는 상인의 책임을 줄이고 민감한 사용자 정보를 보호하는 데 도움이 됩니다.
다음은 이 명세의 범위에 포함되지 않습니다:
이 섹션은 비규범적입니다.
API를 사용하려면 개발자는 여러 핵심 정보를 제공하고 관리해야 합니다. 이러한 정보들은
PaymentRequest
생성자에 인수로 전달되며,
이후 사용자에게 표시되는 결제 요청을 업데이트하는 데 사용됩니다. 즉, 다음과 같은 정보들입니다:
PaymentMethodData
의 시퀀스로,
사이트가 지원하는 결제 방식을 나타냅니다(예: "카드 기반 결제를 지원하지만 Visa와 MasterCard 신용카드만
지원합니다.").
PaymentDetailsInit
사전입니다. 여기에는 총 비용과,
선택적으로 구매되는 물리적 상품 또는 서비스의 목록과 배송 옵션이 포함됩니다. 또한 선택적으로 결제 방식에 대한
"수정자"를 포함할 수 있습니다. 예를 들어, "네트워크 X에 속한 카드로 결제하면 미화 3.00달러의 처리 수수료가 부과됩니다."
PaymentOptions
로 전달합니다
(예: 물리적 상품의 경우, 일반적으로 배송할 물리적 주소가 필요합니다. 디지털 상품의 경우에는 이메일이면 충분합니다).
PaymentRequest
가 생성되면
show
()
메서드를 통해 최종 사용자에게 표시됩니다.
show
()
는 사용자가 결제 요청을 확인하면
PaymentResponse
로 이어지는 프라미스를 반환합니다.
새로운 PaymentRequest
를 생성할 때,
상인은 첫 번째 인수(methodData)를 사용하여 사용자가 결제할 수 있는 다양한 방식을 나열합니다
(예: 신용카드, Apple Pay, Google Pay 등). 보다 구체적으로, methodData 시퀀스에는
PaymentMethodData
사전가 포함되며,
상인이 수락하는 결제 방식 식별자와
해당 결제 방식에 특화된 데이터(예: 지원되는 신용카드 네트워크)가 들어 있습니다.
const methodData = [
{
supportedMethods: "https://example.com/payitforward",
data: {
payItForwardField: "ABC",
},
},
{
supportedMethods: "https://example.com/bobpay",
data: {
merchantIdentifier: "XXXX",
bobPaySpecificField: true,
},
},
];
새로운 PaymentRequest
를 생성할 때,
상인은 두 번째 인수(details)로 사용자가 완료해야 하는 거래의 세부 정보를 제공합니다.
여기에는 주문의 총액과 선택적으로 결제 대상에 대한 상세 내역을 제공하는 몇 가지 라인 아이템이 포함됩니다.
const details = {
id: "super-store-order-123-12312",
displayItems: [
{
label: "Sub-total",
amount: { currency: "GBP", value: "55.00" },
},
{
label: "Value-Added Tax (VAT)",
amount: { currency: "GBP", value: "5.00" },
},
],
total: {
label: "Total due",
// The total is GBP£65.00 here because we need to
// add shipping (below). The selected shipping
// costs GBP£5.00.
amount: { currency: "GBP", value: "65.00" },
},
};
여기에서는 details에 두 가지 배송 옵션을 추가하는 방법의 예를 보여줍니다.
const shippingOptions = [
{
id: "standard",
// Shipping by truck, 2 days
label: "🚛 Envío por camión (2 dias)",
amount: { currency: "EUR", value: "5.00" },
selected: true,
},
{
id: "drone",
// Drone shipping, 2 hours
label: "🚀 Drone Express (2 horas)",
amount: { currency: "EUR", value: "25.00" }
},
];
Object.assign(details, { shippingOptions });
특정 네트워크의 카드를 사용할 때 처리 수수료를 추가하는 방법을 보여줍니다. 이때 총액을 재계산해야 함에 유의하세요.
// Certain cards incur a $3.00 processing fee.
const cardFee = {
label: "Card processing fee",
amount: { currency: "AUD", value: "3.00" },
};
// Modifiers apply when the user chooses to pay with
// a card.
const modifiers = [
{
additionalDisplayItems: [cardFee],
supportedMethods: "https://example.com/cardpay",
total: {
label: "Total due",
amount: { currency: "AUD", value: "68.00" },
},
data: {
supportedNetworks: networks,
},
},
];
Object.assign(details, { modifiers });
일부 금융 거래에서는 상인이 구매를 이행하기 위해 사용자가 특정 정보를 제공해야 합니다(예: 물리적 상품 배송이 필요한 경우 사용자의 배송 주소).
이 정보를 요청하기 위해, 상인은 세 번째 선택적 인수(options)를
PaymentRequest
생성자에 전달하여 필요한 정보를 지정할 수 있습니다.
결제 요청이 표시되면 사용자 에이전트는 최종 사용자에게 이 정보를 요청하고, 사용자가 결제 요청을 수락할 때 상인에게 이를 반환합니다.
const options = {
requestPayerEmail: false,
requestPayerName: true,
requestPayerPhone: false,
requestShipping: true,
}
모든 사전 정보가 준비되면,
PaymentRequest
를 구성하고
브라우저가 이를 사용자에게 표시하도록 요청할 수 있습니다:
async function doPaymentRequest() {
try {
const request = new PaymentRequest(methodData, details, options);
// See below for a detailed example of handling these events
request.onshippingaddresschange = ev => ev.updateWith(details);
request.onshippingoptionchange = ev => ev.updateWith(details);
const response = await request.show();
await validateResponse(response);
} catch (err) {
// AbortError, SecurityError
console.error(err);
}
}
async function validateResponse(response) {
try {
const errors = await checkAllValuesAreGood(response);
if (errors.length) {
await response.retry(errors);
return validateResponse(response);
}
await response.complete("success");
} catch (err) {
// Something went wrong...
await response.complete("fail");
}
}
// Must be called as a result of a click
// or some explicit user action.
doPaymentRequest();
사용자가 결제를 수락하기 전에, 사이트는 사용자 입력에 응답하여 결제 요청을 업데이트할 기회를 가집니다. 예를 들어, 추가 배송 옵션 제공(또는 비용 수정), 특정 주소로 배송할 수 없는 항목 제거 등입니다.
const request = new PaymentRequest(methodData, details, options);
// Async update to details
request.onshippingaddresschange = ev => {
ev.updateWith(checkShipping(request));
};
// Sync update to the total
request.onshippingoptionchange = ev => {
// selected shipping option
const { shippingOption } = request;
const newTotal = {
currency: "USD",
label: "Total due",
value: calculateNewTotal(shippingOption),
};
ev.updateWith({ total: newTotal });
};
async function checkShipping(request) {
try {
const { shippingAddress } = request;
await ensureCanShipTo(shippingAddress);
const { shippingOptions, total } = await calculateShipping(shippingAddress);
return { shippingOptions, total };
} catch (err) {
// Shows error to user in the payment sheet.
return { error: `Sorry! we can't ship to your address.` };
}
}
개발자는
shippingAddressErrors
멤버를
PaymentDetailsUpdate
사전에서 사용하여 특정 ContactAddress
의 속성에
검증 오류가 있음을 나타낼 수 있습니다.
shippingAddressErrors
멤버는
AddressErrors
사전로,
물리적 주소의 오류가 있는
필드를 구체적으로 표시하고
최종 사용자에게 보여줄 유용한 오류 메시지를 제공합니다.
request.onshippingaddresschange = ev => {
ev.updateWith(validateAddress(request.shippingAddress));
};
function validateAddress(shippingAddress) {
const error = "Can't ship to this address.";
const shippingAddressErrors = {
city: "FarmVille is not a real place.",
postalCode: "Unknown postal code for your country.",
};
// Empty shippingOptions implies that we can't ship
// to this address.
const shippingOptions = [];
return { error, shippingAddressErrors, shippingOptions };
}
PaymentResponse
의 데이터는 처리를 위해 서버로 POST 전송되는 것이
일반적입니다.
이를 최대한 쉽게 하기 위해,
PaymentResponse
는
기본 toJSON 단계(즉,
.toJSON()
)를 사용하여 객체를 직접 JSON으로 직렬화할 수 있습니다. 이렇게 하면
Fetch
Standard를 사용해
결과 JSON을 서버로 POST 전송하는 작업이 매우 간단해집니다:
async function doPaymentRequest() {
const payRequest = new PaymentRequest(methodData, details);
const payResponse = await payRequest.show();
let result = "";
try {
const httpResponse = await fetch("/process-payment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: payResponse.toJSON(),
});
result = httpResponse.ok ? "success" : "fail";
} catch (err) {
console.error(err);
result = "fail";
}
await payResponse.complete(result);
}
doPaymentRequest();
교차 출처
iframe
이
결제 요청 API를 호출할 수 있음을 나타내려면,
allow
속성에 "payment" 키워드를 함께 지정하여
iframe
요소에 설정하면 됩니다.
<iframe
src="https://cross-origin.example"
allow="payment">
</iframe>
만약
iframe
이
결제 요청 API를 지원하는 여러 출처 간을 탐색하게 될 경우,
allow
를
"payment *"
로 설정할 수 있습니다.
Permissions Policy 명세에서
추가 세부 사항과 예시를 확인할 수 있습니다.
WebIDL[SecureContext, Exposed=Window]
interface PaymentRequest
: EventTarget {
constructor
(
sequence<PaymentMethodData
> methodData,
PaymentDetailsInit
details,
optional PaymentOptions
options = {}
);
[NewObject]
Promise<PaymentResponse
> show
(optional Promise<PaymentDetailsUpdate
> detailsPromise);
[NewObject]
Promise<undefined> abort
();
[NewObject]
Promise<boolean> canMakePayment
();
readonly attribute DOMString id
;
readonly attribute ContactAddress? shippingAddress
;
readonly attribute DOMString? shippingOption
;
readonly attribute PaymentShippingType
? shippingType
;
attribute EventHandler onshippingaddresschange
;
attribute EventHandler onshippingoptionchange
;
attribute EventHandler onpaymentmethodchange
;
};
개발자는 결제 요청을 만들기 위해 PaymentRequest
를 생성합니다.
이는 일반적으로 사용자가 결제 프로세스를 시작하는 행위(예: 웹사이트에서 "Buy", "Purchase", "Checkout"
버튼을 누르기, 인터랙티브 게임에서 "Power Up"을 선택하기, 주차 구조물의 키오스크에서 결제하기 등)와 연관됩니다.
PaymentRequest
는 사용자가 입력을 제공하는 동안
(사용자가 결제 요청을 승인하거나 거부하는 시점까지) 개발자가 사용자 에이전트와 정보를 교환할 수 있도록 합니다.
shippingAddress
,
shippingOption
, 그리고
shippingType
속성은
처리 중에 requestShipping
멤버가 설정되어 있는
경우 채워집니다.
request의 결제 관련 브라우징 컨텍스트는 해당
PaymentRequest
의 관련 전역 객체의 브라우징
컨텍스트의
최상위
브라우징 컨텍스트입니다. 모든 결제 관련 브라우징 컨텍스트는 한 번에 하나
이상의 결제 UI가 표시되는 것을 방지하는 결제 요청 표시 중 불리언을 갖습니다.
결제 요청 표시 중 불리언은 단일 브라우저 탭에서 둘 이상의 결제 UI가 표시되는 것을 막을 뿐입니다. 그러나 결제 핸들러는 사용자 에이전트가 모든 브라우저 창과 탭에 걸쳐 단 하나의 결제 UI만 표시하도록 제한할 수 있습니다. 다른 결제 핸들러는 서로 다른 브라우저 탭에 걸쳐 결제 UI 표시를 허용할 수도 있습니다.
PaymentRequest
는 제공된
PaymentMethodData
methodData 시퀀스(해당
결제 방식별 data
포함),
PaymentDetailsInit
details, 그리고
PaymentOptions
options를 사용하여 구성됩니다.
PaymentRequest(methodData,
details, options)
생성자는 다음과 같이 동작해야 합니다(MUST):
Document
가 사용이
허용되지 않은 경우
"payment"
권한에 대해, "SecurityError
"
DOMException
을 throw합니다.
TypeError
를
발생시키며,
선택적으로
개발자에게 최소 하나의 결제 방식이 필요함을 알립니다.
supportedMethods
로
결제
방식 식별자를 검증하는 단계를 실행합니다.
결과가 false이면 RangeError
예외를 던집니다.
선택적으로, 결제 방식 식별자가 유효하지 않음을 개발자에게 알립니다.
supportedMethods
를
기본 URL 파서로 파싱한
결과로 둡니다:
supportedMethods
로
설정합니다.
RangeError
DOMException
을
던지며,
선택적으로
해당 결제 방식 식별자가
중복임을 개발자에게 알립니다.
data
멤버가 없으면
serializedData를 null로 둡니다.
그렇지 않으면 serialize를
사용해
paymentMethod.data
를 JSON 문자열로 변환한
결과를
serializedData로 둡니다. 예외가 발생하면 재던집니다.
supportedMethods
를
정의하는 명세가
추가 데이터 유형을 지정하는
경우:
converting을 통해 object를 추가 데이터 유형의 IDL 값으로 변환한 결과를 idl로 둡니다. 예외가 발생하면 재던집니다.
해당 명세에서 정의한
paymentMethod.supportedMethods
에
대해
결제 방식 데이터를
검증하는 단계를
object에 대해 실행합니다. 예외가 발생하면 재던집니다.
이 단계들은 IDL 타입 변환 및 검증 오류가 가능한 한 이른 시점에 포착되도록 보장합니다.
supportedMethods
,
serializedData)를 serializedMethodData에 추가합니다.
total
.amount
.
예외가 발생하면 재던집니다.
displayItems
멤버가
존재하면, details.displayItems
의 각
item에 대해:
amount
. 예외가 발생하면 재던집니다.
requestShipping
멤버가
존재하고 true로 설정된 경우, 배송 옵션을 처리합니다:
sequence
<PaymentShippingOption
>로
둡니다.
shippingOptions
멤버가 존재하면:
shippingOptions
의
각 option에 대해:
shippingOptions
를
options로 설정합니다.
sequence
<PaymentDetailsModifier
>로
둡니다.
modifiers
멤버가
존재하면:
modifiers
로
설정합니다.
total
멤버가 존재하면:
total
.amount
.
예외가 발생하면 재던집니다.
additionalDisplayItems
멤버가 modifier에 존재하면,
modifier.additionalDisplayItems
의
각 item에 대해:
amount
.
예외가 발생하면 재던집니다.
data
멤버가 없으면 serializedData를 null로 둡니다.
그렇지 않으면
serialize를
통해
modifier.data
를
JSON 문자열로 변환한 결과를 serializedData로 둡니다. 예외가 발생하면 재던집니다.
supportedMethods
,
serializedData)를 serializedModifierData에 추가합니다.
data
멤버를 제거합니다.
modifiers
를
modifiers로 설정합니다.
PaymentRequest
로 둡니다.
[[handler]]
를
null
로 설정합니다.
[[options]]
를
options로 설정합니다.
[[state]]
를
"created"로 설정합니다.
[[updating]]
을 false로 설정합니다.
[[details]]
를
details로 설정합니다.
[[serializedModifierData]]
를
serializedModifierData로 설정합니다.
[[serializedMethodData]]
를
serializedMethodData로 설정합니다.
[[response]]
를 null로 설정합니다.
shippingOption
속성 값을 selectedShippingOption으로 설정합니다.
shippingAddress
속성 값을
null로 설정합니다.
requestShipping
이 true로 설정되어
있으면,
request의 shippingType
속성 값을 options.shippingType
으로 설정합니다. 그렇지 않으면
null로 설정합니다.
가져올 때, id
속성은 이
PaymentRequest
의
[[details]]
.id
를 반환합니다.
감사 및 정산 목적을 위해, 상인은 각 거래에 대해 고유 식별자를
id
속성과 연계할 수 있습니다.
개발자가 결제 요청에 대한 사용자 상호작용을 시작하고자 할 때
show
()
메서드를 호출합니다.
show
()
메서드는
Promise
를 반환하며,
사용자가 결제
요청을 수락하면
해결됩니다. show
()
메서드가
반환된 후 결제 요청을 지원하기 위한 어떤 형태의 사용자 인터페이스가 사용자에게 표시됩니다.
여러 브라우징 컨텍스트가 동시에
show
()
메서드를 호출하는 경우에
무엇이 일어나는지는 각 결제 핸들러가 제어합니다.
예를 들어, 일부 결제 핸들러는 서로 다른 브라우저 탭/창에서 여러 결제 UI를 표시하도록 허용할 수 있습니다. 다른 결제 핸들러는 전체 사용자 에이전트에 대해 단 하나의
결제 UI만 허용할 수 있습니다.
show(optional detailsPromise)
메서드는 다음과 같이 동작해야 합니다(MUST):
SecurityError
"
DOMException
과
함께 반환합니다.
이는 예를 들어 리디렉트 후 사용자 활성화가 없을 수 있는 리디렉트 플로우를 지원하기 위해 사용자 에이전트가 사용자 활성화를 요구하지 않도록 허용합니다. 보안 고려사항은 19.9 사용자 활성화 요구사항을 참고하십시오.
또한
issue #1022에서 사용자 에이전트가
show
()
에 대해
사용자 활성화를 요구해야 하는지에 대한 보다 구체적인 지침을 명세에 제공하는 방안에 관해 논의하고 있습니다.
Document
로 둡니다.
AbortError
"
DOMException
으로
거부된 프라미스를
반환합니다.
"visible"
이 아니면,
"AbortError
"
DOMException
으로
거부된 프라미스를
반환합니다.
선택적으로, 사용자 에이전트가 사용자를 보호하기 위해
show
()
호출을 허용하지 않으려는
경우,
"SecurityError
"
DOMException
으로
거부된 프라미스를 반환합니다. 예를 들어,
사용자 에이전트는
show
()
를 페이지가 호출할 수 있는
빈도를 제한할 수 있습니다. 자세한 내용은
19.
개인정보 보호 및 보안 고려사항을 참고하십시오.
[[state]]
가
"created"가 아니면,
"InvalidStateError
"
DOMException
으로
거부된 프라미스를
반환합니다.
[[state]]
를
"closed"로 설정합니다.
AbortError
"
DOMException
으로
거부된
프라미스를 반환합니다.
[[state]]
를
"interactive"로 설정합니다.
[[acceptPromise]]
를
acceptPromise로 설정합니다.
선택적으로:
AbortError
"
DOMException
으로
거부합니다.
[[state]]
를
"closed"로 설정합니다.
[[serializedMethodData]]
의 각
paymentMethod 튜플에 대해:
object
로 둡니다.
[[state]]
를
"closed"로 설정합니다.
[[state]]
를
"closed"로 설정합니다.
NotSupportedError
"
DOMException
으로
거부합니다.
사용자에게 handlers와 상호작용할 수 있는 사용자 인터페이스를 표시합니다. 사용자 에이전트는 결제 방식을 표시할 때 사용자의 선호도를 SHOULD 우선시해야 합니다. 사용자 인터페이스는 가능하다면 document의 문서 요소의 언어와 일치하는 언어 및 로케일 기반 형식으로 표시되어야 하며(SHOULD), 그렇지 않다면 적절한 대체값을 사용해야 합니다.
PaymentRequest
의
세부 정보 업데이트 알고리즘을 실행합니다.
detailsPromise가 어떻게 완료되는지에 따라
PaymentRequest
의
세부 정보 업데이트 알고리즘이
결제 UI 동작 방식을 결정합니다. 즉, detailsPromise가
거부되면
결제 요청은 중단되고, detailsPromise가
이행되면
사용자 에이전트는 결제 요청 UI를 다시 활성화하고 결제 흐름이 계속될 수 있습니다.
[[handler]]
를 최종 사용자가 선택한
결제 핸들러로 설정합니다.
[[serializedModifierData]]
의 각
tuple에 대해:
[[handler]]
의
결제 방식
식별자와 일치하면,
tuple의 두 번째 요소(직렬화된 메서드 데이터)를 modifiers에 추가합니다.
paymentMethod 튜플의 두 번째 요소(변환된 값)를 변환하여 전달하고, modifiers도 함께 전달합니다. 선택적으로, 사용자 에이전트는 사용자 선택 결제 핸들러가 사용자를 결제 과정으로 안내할 수 있도록 request에서 적절한 데이터를 보내야 합니다(SHOULD). 여기에는 request의 다양한 속성과 기타 내부 슬롯이 포함됩니다(적절한 경우 개인정보 보호 사유로 일부는 제외될 수 있음).
[[serializedModifierData]]
내부
슬롯에서
적용 가능한 여러 수정자를 처리하는 방식은
결제 핸들러마다 다르며 본 명세의 범위를 벗어납니다.
그럼에도 불구하고 결제 핸들러는 리스트의 항목에 대해
"마지막 항목 우선(last one wins)" 접근 방식을 사용할 것을 RECOMMENDED합니다:
즉, 리스트 끝의 항목이 리스트 시작의 어떤 항목보다 항상 우선합니다(아래 예시 참조).
acceptPromise는 이후 사용자 인터페이스와의 상호작용을 통해 트리거되는 사용자가 결제 요청을 수락하는 알고리즘이나 사용자가 결제 요청을 중단하는 알고리즘에 의해 해결되거나 거부됩니다.
사용자 인터페이스가 표시되는 동안 document가 완전히 활성화됨이 아니게 되거나, 이 단계에 도달할 때까지 그렇게 되었다면:
개발자가 abort
()
메서드를 호출하여
사용자 에이전트에게 결제 request를 중단하고
표시된 사용자 인터페이스를 제거하도록 지시할 수 있습니다.
abort
()
는
show
()
메서드가 호출된 후
(참조: 상태) 이 인스턴스의
[[acceptPromise]]
가
해결되기 전에만 호출할 수 있습니다. 예를 들어, 판매 중인 상품이 제한된 시간 동안만
이용 가능한 경우 개발자는 이를 수행할 수 있습니다. 허용된 시간 내에 사용자가 결제 요청을
수락하지 않으면 요청이 중단됩니다.
사용자 에이전트가 항상 요청을 중단할 수 있는 것은 아닙니다.
예를 들어, 사용자 에이전트가 요청 책임을 다른 앱에 위임한 경우가
있습니다. 이 상황에서는
abort
()
가 반환된
Promise
를 거부합니다.
또한, 사용자가 결제 요청을 중단하는 경우의 알고리즘을 참조하십시오.
abort
()
메서드는 다음과 같이 동작해야
합니다(MUST):
[[response]]
가 null이 아니고,
request.[[response]]
.[[retryPromise]]
가 null이 아니면, "InvalidStateError
"
DOMException
으로
거부된 프라미스를
반환합니다.
[[state]]
의 값이
"interactive"가 아니면,
"InvalidStateError
"
DOMException
으로
거부된 프라미스를
반환합니다.
InvalidStateError
"
DOMException
으로
promise를 거부하고 이 단계를 중단합니다.
[[state]]
를
"closed"로 설정합니다.
[[acceptPromise]]
를
"AbortError
"
DOMException
으로
거부합니다.
canMakePayment
()
메서드는 개발자가
사용자 에이전트가 원하는
결제 방식 중 하나를 지원하는지 확인하기 위해 사용할 수 있습니다.
자세한 내용은 19.8
canMakePayment()
보호를 참조하십시오.
canMakePayment
()
의
결과가 true라고 해서 사용자가 결제를 위한 프로비저닝된 수단을 이미 준비해 놓았음을 의미하지는 않습니다.
canMakePayment
()
메서드는 can make payment 알고리즘을 실행해야 합니다(MUST).
PaymentRequest
의 shippingAddress
속성은 사용자가 배송 주소를
제공할 때 채워지며, 기본값은 null입니다.
사용자가 배송 주소를 제공할 때 shipping address changed
알고리즘이 실행됩니다.
PaymentRequest
의 shippingType
속성은 거래를 이행하기 위해 사용되는 배송
유형입니다.
이 값은 PaymentShippingType
열거형
값이거나,
개발자가 구성
시점에 제공하지 않은 경우 null입니다.
(참조: PaymentOptions
의 shippingType
멤버).
PaymentRequest
의 onshippingaddresschange
속성은
EventHandler
로,
PaymentRequestUpdateEvent
중 shippingaddresschange
와 명명된 이벤트를 처리합니다.
PaymentRequest
의 shippingOption
속성은 사용자가 배송 옵션을 선택할
때 채워지며, 기본값은 null입니다.
사용자가 배송 옵션을 선택할 때 shipping option changed
알고리즘이 실행됩니다.
PaymentRequest
의 onshippingoptionchange
속성은
EventHandler
로,
PaymentRequestUpdateEvent
중 shippingoptionchange
와 명명된 이벤트를 처리합니다.
PaymentRequest
의 onpaymentmethodchange
속성은 EventHandler
로,
PaymentMethodChangeEvent
중 "paymentmethodchange
"와 명명된 이벤트를 처리합니다.
PaymentRequest
의 인스턴스는
아래 표에 나열된 내부 슬롯과
함께 생성됩니다:
내부 슬롯 | 설명 (비규범적) |
---|---|
[[serializedMethodData]] |
생성자에 제공된 methodData 로,
지원되는 메서드와 문자열 또는 null로 표현된 데이터(원래 객체 형식 대신)로 구성된 튜플로 나타냅니다.
|
[[serializedModifierData]] |
각 data 멤버의 직렬화된 문자열 형식을
포함하는 리스트로,
이는 해당 시퀀스 [[details]] .modifier 의 각 항목과 일치하거나,
그러한 멤버가 없는 경우 null입니다.
|
[[details]] |
결제 요청의 현재 PaymentDetailsBase 로,
생성자에 처음 제공된 후 updateWith ()
호출로 업데이트됩니다.
참고로
data 멤버는
PaymentDetailsModifier 인스턴스의
modifiers 멤버에서 제거되며,
대신 직렬화된 형식으로
[[serializedModifierData]]
내부
슬롯에 저장됩니다.
|
[[options]] |
생성자에 제공된 PaymentOptions .
|
[[state]] |
결제 요청의 현재 상태로, 아래 상태로 전환됩니다:
상태 전환은 아래 그림에 설명되어 있습니다: show ()
메서드는 상태를
"interactive"로 변경합니다. 그 후,
abort ()
메서드 또는 기타 오류가 상태를
"closed"로 전환할 수 있습니다;
마찬가지로 사용자가 결제 요청을
수락하는 알고리즘과
사용자가
결제 요청을 중단하는 알고리즘도
상태를
"closed"로 변경합니다.
|
[[updating]] |
updateWith ()
호출로 결제 요청을 업데이트하기 위한 대기 중인 작업이 있으면 true, 그렇지 않으면 false입니다.
|
[[acceptPromise]] |
show () 호출 시 생성된
대기 중인 Promise 로,
사용자가 결제 요청을 수락하면 해결됩니다.
|
[[response]] |
null이거나, 이
PaymentRequest 에
의해 인스턴스화된
PaymentResponse 입니다.
|
[[handler]] |
이
PaymentRequest 와
연관된
결제 핸들러.
초기값은 null 입니다.
|
WebIDLdictionary PaymentMethodData
{
required DOMString supportedMethods
;
object data
;
};
PaymentMethodData
사전은 지원되는
결제
방식 집합 및 해당 방식들에 대한 관련
결제
방식별 데이터를 나타내는 데 사용됩니다.
supportedMethods
멤버
data
멤버
supportedMethods
의 값이 배열에서 문자열로 변경되었으나, 웹의 기존 콘텐츠와 호환성을 유지하기 위해 이름은 복수형으로 남겨졌습니다.
WebIDLdictionary PaymentCurrencyAmount
{
required DOMString currency
;
required DOMString value
;
};
PaymentCurrencyAmount
사전은 금액을 제공하는 데 사용됩니다.
currency
멤버
[ISO4217] 올바르게 형성된 3-문자 알파벳 코드(즉, 숫자 코드는 지원되지 않음)입니다. 정규 형식은 대문자입니다. 그러나 로컬화된 통화 기호가 제공되는 통화 코드 조합은 구현에 따라 다를 수 있습니다.
금액을 표시할 때, 사용자 에이전트가 통화 코드를 표시하는 것이 권장되지만 통화 기호를 표시하는 것은 선택사항입니다. 이는 통화 기호가 여러 통화에서 사용되므로 모호할 수 있기 때문입니다(예: "$"는 USD, AUD, NZD, CAD 등을 의미할 수 있음).
사용자 에이전트는 OS 규칙(예: 로컬화 목적)을 준수하기 위해 currency
멤버를 표시 형식에 맞게 조정할 수
있습니다(MAY).
이 명세를 구현하는 사용자 에이전트는 ECMAScript의 isWellFormedCurrencyCode
추상 작업을 통해
[ISO4217]의 3-문자 코드 형식을 강제합니다.
이는 check and canonicalize amount 알고리즘의
일부로 호출됩니다.
코드가 [ISO4217] 정의 형식에 맞지 않으면
RangeError
가
발생합니다.
현재 구현은 공식 [ISO4217] 목록에 포함되지 않은 올바르게 형성된 통화 코드(예: XBT, XRP 등)의 사용을 허용합니다. 제공된 코드가 브라우저가 표시 방법을 알고 있는 통화인 경우, 구현은 일반적으로 사용자 인터페이스에 적절한 통화 기호를 표시합니다 (예: "USD"는 U+0024 달러 기호($)로 표시되고, "GBP"는 U+00A3 파운드 기호(£)로 표시되며, "PLN"은 U+007A U+0142 즈워티(zł)로 표시되고, 비표준 "XBT"는 U+0243 라틴 대문자 B와 스트로크(Ƀ)로 표시될 수 있음).
ISO는 디지털 통화를 포함하기 위해 작업을 진행 중이며, 이는 [ISO4217] 레지스트리 업데이트 또는 완전히 새로운 레지스트리를 초래할 수 있습니다. 커뮤니티는 이것이 비표준 3-문자 코드 사용으로 인해 발생한 모호성을 해결할 것으로 예상합니다. 예를 들어, "BTC"가 비트코인을 나타내는지 아니면 미래의 부탄 통화를 나타내는지에 대한 질문이 있습니다. 발행 시점에서는 이러한 진화가 어떤 형태를 취할 것인지, 또는 작업이 완료될 시간 프레임조차 불분명합니다. W3C 웹 결제 작업 그룹은, 앞으로 이 명세의 개정이 관련 ISO 레지스트리와 호환되도록 ISO와 협력하고 있습니다.
value
멤버
{
"currency": "OMR",
"value": "1.234"
}
JavaScript 문자열이 유효한 소수 통화 값인지 여부는 다음 순서로 구성된 코드 포인트로 판단됩니다:
^-?[0-9]+(\.[0-9]+)?$
금액 확인
및 정규화를
PaymentCurrencyAmount
amount에 대해 실행하려면, 다음 단계를 따르십시오:
currency
)
결과가 false인 경우 RangeError
예외를
발생시키고,
선택적으로 개발자에게 통화가 유효하지 않음을 알립니다.
value
가
유효한 소수 통화 값이 아닌 경우,
TypeError
를
발생시키고, 선택적으로 개발자에게 통화가 유효하지 않음을 알립니다.
currency
를
ASCII 대문자로 변환한 결과로
설정합니다:
amount.currency
.
총 금액 확인 및 정규화를
PaymentCurrencyAmount
amount에 대해 실행하려면, 다음 단계를 따르십시오:
value
의 첫 번째
코드 포인트가 U+002D (-)인 경우,
TypeError
를
발생시키고, 선택적으로 개발자에게 총 금액의 값은 음수일 수 없음을 알립니다.
WebIDLdictionary PaymentDetailsBase
{
sequence<PaymentItem
> displayItems
;
sequence<PaymentShippingOption
> shippingOptions
;
sequence<PaymentDetailsModifier
> modifiers
;
};
displayItems
멤버
PaymentItem
사전의 시퀀스는
사용자 에이전트가 표시할 수 있는
결제 요청의 항목을 포함합니다.
shippingOptions
멤버
사용자가 선택할 수 있는 다양한 배송 옵션을 포함하는 시퀀스입니다.
시퀀스 내 항목에
selected
멤버가
true로 설정된 경우, 이 배송 옵션이 기본적으로 사용되며
shippingOption
은
이 옵션의
id
로 설정됩니다.
시퀀스 내에서 여러 항목이
selected
로
true로 설정된 경우,
사용자 에이전트가 시퀀스의 마지막 항목을 선택합니다.
shippingOptions
멤버는
PaymentRequest
가
PaymentOptions
와
requestShipping
이
true로 설정된 상태로 생성된 경우에만 사용됩니다.
modifiers
멤버
PaymentDetailsModifier
사전의
시퀀스입니다. 예를 들어, 결제 방법을 기준으로 총 금액을 조정할 수 있습니다.
WebIDLdictionary PaymentDetailsInit
: PaymentDetailsBase
{
DOMString id
;
required PaymentItem
total
;
};
PaymentDetailsBase
사전에서 상속된 멤버 외에도,
다음 멤버가
PaymentDetailsInit
사전의 일부입니다:
id
멤버
total
멤버
PaymentItem
입니다.
WebIDLdictionary PaymentDetailsUpdate
: PaymentDetailsBase
{
DOMString error
;
PaymentItem
total
;
AddressErrors
shippingAddressErrors
;
PayerErrors
payerErrors
;
object paymentMethodErrors
;
};
PaymentDetailsUpdate
사전은 updateWith
()
를
사용하여 결제 요청을 업데이트하는 데 사용됩니다.
PaymentDetailsBase
사전에서 상속된 멤버 외에도,
다음 멤버가
PaymentDetailsUpdate
사전의 일부입니다:
error
멤버
updateWith
()
를
사용하여 업데이트될 때,
PaymentDetailsUpdate
는
error
멤버에 메시지를 포함할 수 있으며,
이는 PaymentDetailsUpdate
에 유효한
shippingOptions
가 포함되지 않는
경우 사용자에게 표시됩니다.
(결제 요청이
PaymentRequest
의
requestShipping
옵션을 true로
설정하여 생성된 경우)
total
멤버
PaymentItem
을 포함합니다.
이 명세의 알고리즘은
PaymentDetailsUpdate
사전을 허용하며
total
.amount
.value
가 음수인 경우 예외를
발생시킵니다.
shippingAddressErrors
멤버
payerErrors
멤버
paymentMethodErrors
멤버
결제 방법과 관련된 구체적인 오류입니다.
WebIDLdictionary PaymentDetailsModifier
{
required DOMString supportedMethods
;
PaymentItem
total
;
sequence<PaymentItem
> additionalDisplayItems
;
object data
;
};
PaymentDetailsModifier
사전은 PaymentDetailsBase
를 결제 방법 식별자를 기반으로 수정하는 세부사항을 제공합니다.
다음 멤버를 포함합니다:
supportedMethods
멤버
PaymentDetailsModifier
의 멤버는 사용자가 이
결제 방법을 선택했을 때만 적용됩니다.
total
멤버
PaymentItem
값으로,
total
멤버를 덮어씁니다.
이 멤버는
PaymentDetailsInit
사전 내의
결제 방법 식별자와
supportedMethods
멤버와 관련됩니다.
additionalDisplayItems
멤버
PaymentItem
사전의 시퀀스입니다.
이는
displayItems
멤버에 추가되며,
PaymentDetailsBase
사전 내
결제 방법 식별자와
supportedMethods
멤버에
관련됩니다.
이 멤버는 일반적으로 선택한
결제 방법에 대해 다른
total
금액의 이유를 나타내는 할인 또는 추가 요금 항목을
추가하는 데 사용됩니다.
표시할 수 있습니다.
개발자는
total
금액이
displayItems
및
additionalDisplayItems
의
합계인지 확인해야 합니다.
data
멤버
WebIDLenum PaymentShippingType
{
"shipping
",
"delivery
",
"pickup
"
};
shipping
"
delivery
"
pickup
"
WebIDLdictionary PaymentOptions
{
boolean requestPayerName
= false;
boolean requestBillingAddress
= false;
boolean requestPayerEmail
= false;
boolean requestPayerPhone
= false;
boolean requestShipping
= false;
PaymentShippingType
shippingType
= "shipping";
};
PaymentOptions
사전은
PaymentRequest
생성자에 전달되며, 결제 요청에 대한 옵션을 제공합니다.
requestBillingAddress
멤버
requestPayerName
멤버
requestPayerEmail
멤버
requestPayerPhone
멤버
requestShipping
멤버
shippingType
멤버
PaymentShippingType
열거형
값입니다.
일부 거래는 배송을 위해
주소가 필요하지만, "배송"이라는 용어가 적합하지 않을 수
있습니다.
예를 들어, "피자 배달"은 "피자 배송"이 아니며, "세탁물 픽업"은 "세탁물 배송"이 아닙니다.
shippingType
멤버는 결제 요청에 대한 사용자
인터페이스에만 영향을 미칩니다.
WebIDLdictionary PaymentItem
{
required DOMString label
;
required PaymentCurrencyAmount
amount
;
boolean pending
= false;
};
하나 이상의 PaymentItem
사전의 시퀀스가
PaymentDetailsBase
사전에 포함되어,
결제 요청의 목적과 요청된 값을 나타냅니다.
label
멤버
amount
멤버
PaymentCurrencyAmount
입니다.
pending
멤버
amount
멤버가 최종 금액이 아님을 의미합니다. 이는 일반적으로 배송 주소 또는 배송 옵션 선택에 따라 달라지는
배송비나 세금 금액과 같은 항목을 표시하는 데 사용됩니다.
사용자
에이전트는 결제 요청에 대한 사용자 인터페이스에서
대기 중인 필드를 표시할 수 있습니다.
WebIDLdictionary PaymentCompleteDetails
{
object? data
= null;
};
PaymentCompleteDetails
사전은 결제 요청이 완료되었을 때 가맹점 웹사이트에서 결제 처리기로 추가 정보를 제공합니다.
PaymentCompleteDetails
사전은 다음 멤버를 포함합니다:
data
멤버
PaymentResponse
결제 방법에 필요할 수 있는 선택적 정보를 제공하는 객체입니다. 제공된 경우,
이는 직렬화됩니다.
WebIDLenum PaymentComplete
{
"fail
",
"success
",
"unknown
"
};
fail
"
success
"
unknown
"
WebIDLdictionary PaymentShippingOption
{
required DOMString id
;
required DOMString label
;
required PaymentCurrencyAmount
amount
;
boolean selected
= false;
};
PaymentShippingOption
사전은 배송 옵션을 설명하는 멤버를 포함합니다. 개발자는
updateWith
()
메서드를 호출하여 변경 이벤트에 응답하여 사용자에게 하나 이상의 배송 옵션을 제공할 수 있습니다.
id
멤버
PaymentShippingOption
을
참조하는 데 사용되는 문자열 식별자입니다.
이는 주어진 PaymentRequest
에 대해 고유해야 합니다.
label
멤버
amount
멤버
PaymentCurrencyAmount
입니다.
selected
멤버
PaymentShippingOption
임을 나타냅니다.
사용자
에이전트는 사용자 인터페이스에서 기본적으로 이 옵션을 표시해야 합니다.
WebIDL[SecureContext, Exposed=Window]
interface PaymentResponse
: EventTarget {
[Default] object toJSON();
readonly attribute DOMString requestId
;
readonly attribute DOMString methodName
;
readonly attribute object details
;
readonly attribute ContactAddress? shippingAddress
;
readonly attribute DOMString? shippingOption
;
readonly attribute DOMString? payerName
;
readonly attribute DOMString? payerEmail
;
readonly attribute DOMString? payerPhone
;
[NewObject]
Promise<undefined> complete
(
optional PaymentComplete
result = "unknown",
optional PaymentCompleteDetails
details = {}
);
[NewObject]
Promise<undefined> retry
(optional PaymentValidationErrors
errorFields = {});
attribute EventHandler onpayerdetailchange
;
};
PaymentResponse
는 사용자가 결제 방법을 선택하고 결제 요청을 승인했을 때
반환됩니다.
retry(errorFields)
메서드는
다음과 같이 반드시 동작해야 합니다:
[[request]]
로
둔다.
Document
로 둔다.
AbortError
"
DOMException
으로
거부된 프로미스를
반환한다.
[[complete]]
가 true이면,
"InvalidStateError
"
DOMException
으로
거부된 프로미스를
반환한다.
[[retryPromise]]
가 null이 아니면,
"InvalidStateError
"
DOMException
으로
거부된 프로미스를
반환한다.
[[state]]
를
"interactive"로 설정한다.
[[retryPromise]]
를
retryPromise로 설정한다.
[[options]]
.requestPayerName
가 false이고,
errorFields.payer
.name
이 존재하는 경우.
[[options]]
.requestPayerEmail
이 false이고,
errorFields.payer
.email
이 존재하는 경우.
[[options]]
.requestPayerPhone
이 false이고,
errorFields.payer
.phone
이 존재하는 경우.
[[options]]
.requestShipping
이 false이고,
errorFields.shippingAddress
가 존재하는 경우.
paymentMethod
멤버가 전달되었고,
response.methodName
를 정의하는
명세에서 이를 요구하는 경우에는,
변환하여
errorFields의
paymentMethod
멤버를 거기서 지정된 타입의 IDL 값으로 만든다. 그렇지 않으면
변환하여
object
로 만든다.
error
멤버가
전달된 경우, 그 오류를 사용자 에이전트의 UI에 표시한다. 멤버의 값이 빈 문자열인 경우,
사용자 에이전트는 대체할 수 있다 적절한 오류 메시지로 값을 대체해도 된다.
[[retryPromise]]
를 null로 설정한다.
retryPromise는 이후 사용자가 결제 요청을 수락하는 알고리즘에 의해 이행되거나, 사용자가 결제 요청을 중단하는 알고리즘 또는 업데이트 중단에 의해 거부된다.
WebIDLdictionary PaymentValidationErrors
{
PayerErrors
payer
;
AddressErrors
shippingAddress
;
DOMString error
;
object paymentMethod
;
};
payer
멤버
shippingAddress
멤버
PaymentResponse
의
shippingAddress
와 관련된
유효성 검사 오류를 나타냅니다.
error
멤버
error
멤버만 전달하여
유효성 문제에 대한 일반적인 개요를 제공할 수 있으며, 또는
PaymentValidationErrors
사전의
다른 멤버와 함께 전달할 수도 있습니다.
paymentMethod
멤버
WebIDLdictionary PayerErrors
{
DOMString email
;
DOMString name
;
DOMString phone
;
};
PayerErrors
는 하나 이상의
지불자 세부정보에 대한 유효성 검사 오류를 표현하는 데 사용됩니다.
지불자 세부정보는 지불자의 이름, 지불자의 전화번호, 지불자의 이메일 중 어느 것이든 해당됩니다.
email
멤버
PaymentResponse
의
payerEmail
속성 값에 해당하는
입력 필드와 대응됩니다.
name
멤버
PaymentResponse
의
payerName
속성 값에 해당하는
입력 필드와 대응됩니다.
phone
멤버
PaymentResponse
의
payerPhone
속성 값에 해당하는
입력 필드와 대응됩니다.
가맹점이 거래를 처리하거나 검증하는 데 사용할 수 있도록 사전 또는
object
형태로
결제 방법에 의해 생성됩니다(선택된
결제 방법에 따라 다름).
requestShipping
멤버가
PaymentOptions
에서 true로 설정된 상태로
PaymentRequest
생성자에 전달된 경우,
shippingAddress
는 사용자가 선택한
전체이자 최종 배송 주소가 됩니다.
requestShipping
멤버가
PaymentOptions
에서 true로 설정된 상태로
PaymentRequest
생성자에 전달된 경우,
shippingOption
은 선택된 배송 옵션의
id
속성이 됩니다.
requestPayerName
멤버가
PaymentOptions
에서 true로 설정된 상태로
PaymentRequest
생성자에 전달된 경우,
payerName
은 사용자가 제공한 이름이 됩니다.
requestPayerEmail
멤버가
PaymentOptions
에서 true로 설정된 상태로
PaymentRequest
생성자에 전달된 경우,
payerEmail
은 사용자가 선택한 이메일 주소가 됩니다.
requestPayerPhone
멤버가
PaymentOptions
에서 true로 설정된 상태로
PaymentRequest
생성자에 전달된 경우,
payerPhone
은 사용자가 선택한 전화번호가 됩니다.
이 결제 응답을 생성한 해당 결제 요청의 id
입니다.
사용자가 결제 요청을 수락하고
[[acceptPromise]]
가 이행된 뒤에
complete
()
메서드가 호출됩니다.
complete
()
메서드를 호출하면
사용자 에이전트에 결제 상호작용이 종료되었음을 알리며
남아 있는 사용자 인터페이스를 닫아야 합니다(SHOULD).
결제 요청이 수락되어 호출자에게
PaymentResponse
가 반환되었지만,
호출자가 complete
()
를 호출하기 전까지는
결제 요청 사용자 인터페이스는 보류 상태로 남습니다. 이때에는 결제 요청이 수락되어 반환되었으므로
사용자 인터페이스가 취소 명령을 제공해서는 안 됩니다. 그러나 문제가 발생하여
개발자가 complete
()
를 호출하지 않으면
사용자 인터페이스가 차단됩니다.
이러한 이유로, 구현은 개발자가
complete
()
를 호출해야 하는
제한 시간을 둘 수 있습니다. 제한 시간이 만료되면 구현은
인자가 없는 상태로 complete
()
가
호출된 것처럼 동작합니다.
complete
()
메서드는
다음과 같이 반드시 동작해야 합니다:
[[complete]]
가 true이면,
"InvalidStateError
"
DOMException
으로
거부된 프로미스를
반환한다.
[[retryPromise]]
가 null이 아니면,
"InvalidStateError
"
DOMException
으로
거부된 프로미스를
반환한다.
data
를
JSON 문자열로 변환한 값으로 둔다.
methodName
을 정의하는 명세에서
요구하는 경우:
[[complete]]
를 true로 설정한다.
개발자가 "payerdetailchange
" 이벤트를 처리할 수 있도록 합니다.
PaymentResponse
의 인스턴스는
다음 표의 내부 슬롯과
함께 생성됩니다:
내부 슬롯 | 설명 (비규범적) |
---|---|
[[complete]] |
결제 요청이 완료된 경우(즉,
complete () 가
호출되었거나,
응답을 더 이상 사용할 수 없게 만드는 치명적 오류가 있었던 경우) true이며,
그렇지 않으면 false입니다.
|
[[request]] |
이 PaymentRequest
인스턴스로부터 생성된
PaymentResponse 입니다.
|
[[retryPromise]] |
null이거나, Promise 로서
사용자가
결제 요청을 수락하면 이행되고,
사용자가 결제 요청을 중단하면 거부됩니다.
|
PaymentRequest
인터페이스는 가맹점이 사용자로부터
배송 및/또는 청구 목적을 위한 물리적 주소를 요청할 수 있게 합니다.
배송 주소와
청구 주소는
물리적 주소입니다.
WebIDLdictionary AddressErrors
{
DOMString addressLine
;
DOMString city
;
DOMString country
;
DOMString dependentLocality
;
DOMString organization
;
DOMString phone
;
DOMString postalCode
;
DOMString recipient
;
DOMString region
;
DOMString sortingCode
;
};
AddressErrors
사전의 멤버들은
물리적 주소의
특정 부분에 대한 유효성 검사 오류를 나타냅니다. 각 사전 멤버는 이중 기능을 갖습니다:
첫째, 멤버가 존재한다는 것은 주소의 특정 부분에 유효성 검사 오류가 있음을 의미합니다.
둘째, 문자열 값은 개발자가 유효성 검사 오류(그리고 최종 사용자가 오류를 어떻게 수정할 수 있는지)를
설명할 수 있게 해줍니다.
사용자가 주소의 일부를 수정할 수 없는 경우가 있을 수 있음을 개발자는 인지해야 합니다. 따라서 사용자가 통제할 수 없는 항목을 수정하도록 요구하지 않도록 유의해야 합니다.
addressLine
멤버
ContactAddress
의
addressLine
속성 값을 제공한 입력 필드에 대응됩니다.
city
멤버
ContactAddress
의
city
속성 값을 제공한 입력 필드에 대응됩니다.
country
멤버
ContactAddress
의
country
속성 값을 제공한 입력 필드에 대응됩니다.
dependentLocality
멤버
ContactAddress
의
dependentLocality
속성 값을 제공한 입력 필드에 대응됩니다.
organization
멤버
ContactAddress
의
organization
속성 값을 제공한 입력 필드에 대응됩니다.
phone
멤버
ContactAddress
의
phone
속성 값을 제공한 입력 필드에 대응됩니다.
postalCode
멤버
ContactAddress
의
postalCode
속성 값을 제공한 입력 필드에 대응됩니다.
recipient
멤버
ContactAddress
의
addressLine
속성 값을 제공한 입력 필드에 대응됩니다.
region
멤버
ContactAddress
의
region
속성 값을 제공한 입력 필드에 대응됩니다.
sortingCode
멤버
ContactAddress
의
sortingCode
속성 값을 제공한 입력 필드에 대응됩니다.
본 명세는 문자열 "payment"로 식별되는 정책으로 제어되는 기능을 정의합니다 [permissions-policy]. 해당 기능의 기본 허용 목록은 'self'입니다.
이 절은 비규범적입니다.
이벤트 이름 | 인터페이스 | 다음 상황에서 디스패치됨… | 대상 |
---|---|---|---|
shippingaddresschange
|
PaymentRequestUpdateEvent
|
사용자가 새 배송 주소를 제공합니다. |
PaymentRequest
|
shippingoptionchange
|
PaymentRequestUpdateEvent
|
사용자가 새 배송 옵션을 선택합니다. |
PaymentRequest
|
payerdetailchange
|
PaymentRequestUpdateEvent
|
사용자가 지불자 이름, 지불자 이메일 또는 지불자 전화번호를 변경합니다( 지불자 세부정보 변경 알고리즘 참조). |
PaymentResponse
|
paymentmethodchange
|
PaymentMethodChangeEvent
|
사용자가 결제 방법을 결제 처리기 내에서 다른 것으로 선택합니다. |
PaymentRequest
|
WebIDL[SecureContext, Exposed=Window]
interface PaymentMethodChangeEvent
: PaymentRequestUpdateEvent
{
constructor
(DOMString type, optional PaymentMethodChangeEventInit
eventInitDict = {});
readonly attribute DOMString methodName
;
readonly attribute object? methodDetails
;
};
가져올 때, 초기화된 값을 반환합니다. 자세한 내용은
methodDetails
멤버와
PaymentMethodChangeEventInit
을
참조하십시오.
가져올 때, 초기화된 값을 반환합니다. 자세한 내용은
methodName
멤버와
PaymentMethodChangeEventInit
을
참조하십시오.
WebIDLdictionary PaymentMethodChangeEventInit
: PaymentRequestUpdateEventInit
{
DOMString methodName
= "";
object? methodDetails
= null;
};
methodName
멤버
methodDetails
멤버
WebIDL[SecureContext, Exposed=Window]
interface PaymentRequestUpdateEvent
: Event {
constructor
(DOMString type, optional PaymentRequestUpdateEventInit
eventInitDict = {});
undefined updateWith
(Promise<PaymentDetailsUpdate
> detailsPromise);
};
PaymentRequestUpdateEvent
는
사용자 상호작용에 응답하여 결제 요청의 세부 정보를 업데이트할 수 있도록 합니다.
PaymentRequestUpdateEvent
의
constructor
(type, eventInitDict)
는
다음과 같이 동작해야 합니다:
PaymentRequestUpdateEvent
의
constructor를
type과 eventInitDict로 호출한 결과로 둔다.
[[waitForUpdate]]
를
false로 설정한다.
updateWith
()
를
detailsPromise와 함께 호출하는 메서드는 다음과 같이
동작해야 합니다:
isTrusted
속성이
false이면,
"InvalidStateError
"
DOMException
을
throw한다.
[[waitForUpdate]]
가
true이면,
"InvalidStateError
"
DOMException
을
throw한다.
PaymentResponse
의
인스턴스이면,
request를
event의
target의
[[request]]
값으로 둔다.
PaymentRequest
의
인스턴스이다.
[[state]]
가
"interactive"가 아니면,
"InvalidStateError
"
DOMException
을
throw한다.
[[updating]]
이 true이면,
"InvalidStateError
"
DOMException
을
throw한다.
[[waitForUpdate]]
를
true로 설정한다.
methodName
속성을 가진 경우,
pmi를
methodName
속성의 값으로 설정한다.
PaymentRequestUpdateEvent
의
인스턴스는 다음 표의
내부
슬롯과
함께 생성됩니다:
내부 슬롯 | 설명 (비규범적) |
---|---|
[[waitForUpdate]] |
updateWith () 로
시작된 업데이트가 현재 진행 중인지 나타내는 불리언입니다.
|
WebIDLdictionary PaymentRequestUpdateEventInit
: EventInit {};
PaymentRequest
객체의
내부
슬롯 [[state]]
가 "interactive"로 설정되면,
사용자
에이전트는
사용자 상호작용에 따라 다음 알고리즘들을 트리거합니다.
결제 가능
여부 알고리즘은
사용자
에이전트가
결제 방법을 사용해 결제를
지원하는지 확인합니다. 이 결제 방법들은
PaymentRequest
가
구성될 때 지정된 것들입니다.
PaymentRequest
객체로 둔다.
[[state]]
가
"created"가 아니면,
"InvalidStateError
"
DOMException
으로
거부된 프로미스를
반환한다.
NotAllowedError
"
DOMException
으로
거부된 프로미스를
반환할 수 있다.
이는 사용자 에이전트가 지문 채취 목적의 남용을 감지하고 방지하기 위한
휴리스틱을 적용할 수 있도록 합니다. 예를 들어 다양한
지원되는 PaymentRequest
객체를
생성하고 여러 결제 방법에 대해
결제 가능 여부 알고리즘을 연달아 트리거하는 것과 같은 경우입니다.
예를 들어, 사용자 에이전트는 해당 호출이 이루어진
최상위
브라우징 컨텍스트나 호출이 이루어진 시간대에 따라
허용되는 성공적인 호출의 수를 제한할 수 있습니다.
[[serializedMethodData]]
안에서:
배송 주소 변경 알고리즘은 사용자가 새로운 배송 주소를 제공할 때 실행됩니다. 이 알고리즘은 다음 단계를 반드시 수행합니다:
PaymentRequest
객체로 둔다.
redactList는 API가 가맹점과 공유하는 수취인 개인 정보의 양을 제한합니다.
가맹점의 경우, 결과로 얻는
ContactAddress
객체는
예를 들어 배송비를 계산하기에 충분한 정보를 제공하지만,
대부분의 경우 수취인을 물리적으로 특정하고 고유하게 식별하기에는
충분하지 않습니다.
불행히도 redactList가 있더라도 수취인의 익명성이 보장되는 것은 아닙니다. 일부 국가에서는 우편번호가 매우 세분화되어 특정 수취인을 고유하게 식별할 수 있기 때문입니다.
shippingAddress
를
address로 설정한다.
shippingaddresschange
"를 사용하여
PaymentRequest 업데이트 알고리즘을 실행한다.
배송 옵션 변경 알고리즘은 사용자가 새로운 배송 옵션을 선택할 때 실행됩니다. 이 알고리즘은 다음 단계를 반드시 수행합니다:
PaymentRequest
객체로 둔다.
shippingOption
속성을, 사용자가 제공한
PaymentShippingOption
의
id
문자열로 설정한다.
shippingoptionchange
"를 사용하여
PaymentRequest 업데이트 알고리즘을 실행한다.
사용자가 methodDetails(이는 사전 또는
object
또는 null)과
methodName(사용자가 상호작용 중인
payment
method identifier를 나타내는 DOMString)과 함께
결제 방법을 변경할 때,
결제 처리기는
MAY 결제
방법 변경 알고리즘을 실행할 수 있다.
사용자가 결제 방법(예: 신용카드)을 선택하거나 변경하면,
PaymentMethodChangeEvent
에는
세금 계산을 수행하기 위한 목적으로 마스킹된 청구지 주소 정보가 포함된다.
마스킹되는 속성에는 다음이 포함되나 이에 국한되지는 않는다:
address line,
dependent
locality,
organization,
phone number,
그리고 recipient.
PaymentRequest
객체로 둔다.
[[updating]]
은 false이다.
한 번에 하나의 업데이트만 수행될 수 있다.
[[state]]
는
"interactive"이다.
paymentmethodchange
"이며,
PaymentMethodChangeEvent
를
사용하여
request에서 발생시킨다.
이때 그
methodName
속성은 methodName으로 초기화하고,
methodDetails
속성은 methodDetails로 초기화한다.
PaymentRequest 업데이트 알고리즘은 위의 다른 알고리즘들에 의해 실행되어,
사용자가 PaymentRequest
request에 변경을 가했음을 나타내는
이벤트를 발생시키며,
이벤트 이름은 name이다:
[[updating]]
은 false이다.
한 번에 하나의 업데이트만 수행될 수 있다.
[[state]]
는
"interactive"이다.
PaymentRequestUpdateEvent
인터페이스를 사용하여 만든 결과로 둔다.
type
속성을
name으로 초기화한다.
[[waitForUpdate]]
가
true이면, 또 다른 업데이트 이벤트가 발생할 수 있는 사용자 인터페이스의 모든 부분을 비활성화한다.
[[waitForUpdate]]
를 true로 설정한다.
사용자 에이전트는 사용자가 사용자 인터페이스에서 payer name 또는 payer email 또는 payer phone을 변경할 때 MUST 지불자 세부정보 변경 알고리즘을 실행해야 한다:
PaymentRequest
객체로 둔다.
[[response]]
가 null이면, 반환한다.
[[response]]
로 둔다.
[[updating]]
은 false이다.
[[state]]
는
"interactive"이다.
[[options]]
로 둔다.
requestPayerName
이
true이면:
payerName
속성을 payer name으로 설정한다.
requestPayerEmail
이 true이면:
payerEmail
을
payer
email로 설정한다.
requestPayerPhone
이 true이면:
payerPhone
을
payer
phone으로 설정한다.
PaymentRequestUpdateEvent
를
사용하여 만든 결과로 둔다.
type
속성을
"payerdetailchange
"로
초기화한다.
[[waitForUpdate]]
가
true이면, 지불자 세부정보에 또 다른 변경을 발생시킬 수 있는
사용자 인터페이스의 모든 부분을 비활성화한다.
[[waitForUpdate]]
를
true로 설정한다.
사용자가 결제 요청을 수락하는 알고리즘은 사용자가 결제 요청을 수락하고 결제 의사를 확인할 때 실행된다. 다음 단계를 수행하기 위해 작업을 큐에 넣어야 한다 (작업 소스: 사용자 상호작용 작업 소스):
PaymentRequest
객체로 둔다.
[[updating]]
이 true이면,
이 알고리즘을 종료하고 추가 동작을 하지 않는다.
사용자 에이전트의 사용자 인터페이스는
이러한 상황이 발생하지 않도록 권장된다.
[[state]]
가
"interactive"가 아니면,
이 알고리즘을 종료하고 추가 동작을 하지 않는다.
사용자 에이전트의 사용자 인터페이스는
이러한 상황이 발생하지 않도록 권장된다.
[[options]]
의
requestShipping
값이
true이면, request의
shippingAddress
속성이 null이거나
shippingOption
속성이
null이면, 이 알고리즘을 종료하고 추가 동작을 하지 않는다.
사용자 에이전트는 이러한 상황이 발생하지 않도록
권장된다.
[[response]]
가 null이 아니면 true,
그렇지 않으면 false로 둔다.
[[response]]
로,
그렇지 않으면 새로운
PaymentResponse
로 둔다.
[[request]]
를
request로 설정한다.
[[retryPromise]]
를 null로 설정한다.
[[complete]]
를 false로 설정한다.
requestId
속성 값을,
request의
[[details]]
.id
의 값으로 설정한다.
[[response]]
를
response로 설정한다.
[[handler]]
로
둔다.
methodName
속성 값을,
handler의
결제 방법 식별자로 설정한다.
details
속성 값을,
handler의
결제 요청에 응답하는 단계를 실행한
결과로 얻은 객체로 설정한다.
[[options]]
의
requestShipping
값이
false이면, response의
shippingAddress
속성 값을
null로 설정한다. 그렇지 않으면:
shippingAddress
속성 값을 shippingAddress로 설정한다.
shippingAddress
속성 값을 shippingAddress로 설정한다.
[[options]]
의
requestShipping
값이
true이면, response의
shippingOption
속성을
request의
shippingOption
속성 값으로
설정한다. 그렇지 않으면 null로 설정한다.
[[options]]
의
requestPayerName
값이
true이면, response의
payerName
속성을
사용자가 제공한 지불자 이름으로 설정하고, 제공되지 않았으면 null로 설정한다.
그렇지 않으면 null로 설정한다.
[[options]]
의
requestPayerEmail
값이
true이면, response의
payerEmail
속성을
사용자가 제공한 지불자 이메일 주소로 설정하고, 제공되지 않았으면 null로 설정한다.
그렇지 않으면 null로 설정한다.
[[options]]
의
requestPayerPhone
값이
true이면, response의
payerPhone
속성을
사용자가 제공한 지불자 전화번호로 설정하고, 제공되지 않았으면 null로 설정한다.
payerPhone
값을 설정할 때,
사용자 에이전트는 [E.164]를
준수하도록 번호를 권장되는 방식으로 서식화해야 한다.
[[state]]
를
"closed"로 설정한다.
[[retryPromise]]
를 undefined로 이행(resolve)한다.
그렇지 않으면,
request.[[acceptPromise]]
를
response로 이행(resolve)한다.
사용자가 결제 요청을 중단하는 알고리즘은 사용자가 현재 상호작용 중인 사용자 인터페이스를 통해 결제 요청을 중단할 때 실행된다. 다음 단계를 수행하기 위해 작업을 큐에 넣어야 한다 (작업 소스: 사용자 상호작용 작업 소스):
PaymentRequest
객체로 둔다.
[[state]]
가
"interactive"가 아니면,
이 알고리즘을 종료하고 추가 동작을 하지 않는다.
사용자 에이전트의 사용자 인터페이스는
이러한 상황이 발생하지 않도록 권장된다.
[[state]]
를
"closed"로 설정한다.
AbortError
"
DOMException
으로 둔다.
[[response]]
로 둔다.
[[complete]]
를 true로 설정한다.
[[retryPromise]]
는
null이 아니다.
[[retryPromise]]
를
error로 거부(reject)한다.
[[acceptPromise]]
를
error로 거부(reject)한다.
PaymentRequest
의 details 업데이트
알고리즘은 PaymentDetailsUpdate
detailsPromise와
PaymentRequest
request, 그리고
DOMString 또는 null(즉, payment method
identifier)인 pmi를 인자로 받는다. 단계들은 detailsPromise의 이행/거부에 따라 조건부로 수행된다.
detailsPromise가 끝내 완료되지 않으면 결제 요청은 차단된다. 사용자 에이전트는 사용자가 결제 요청을 중단할 수 있는 수단을 제공하는 것이
SHOULD이며, 구현체는 detailsPromise가 합리적인 시간 내에 완료되지 않을 경우
대기 중 업데이트에 대해 타임아웃을 구현할 수
MAY 있다.
타임아웃이 발생하거나, 사용자가 수동으로 중단하거나, payment handler가 해당 결제를 중단하기로 결정한 경우, 사용자 에이전트는 user aborts the payment request algorithm을 MUST 실행해야 한다.
[[updating]]
을 true로 설정한다.
AbortError
"
DOMException
을
전달한다.
PaymentDetailsUpdate
사전으로 얻은 결과로 둔다. 이 과정에서 예외가
발생하면,
업데이트를 중단하고 request와
발생한 예외를 전달한다.
sequence
<PaymentShippingOption
>로 둔다.
total
멤버가
존재하면:
total
.amount
.
예외가 발생하면 업데이트를 중단하고
request와 해당 예외를 전달한다.
displayItems
멤버가 존재하면, 각
item ∈
details.displayItems
에
대하여:
amount
. 예외가
발생하면
업데이트를 중단하고
request와 해당 예외를 전달한다.
shippingOptions
멤버가 존재하고,
request.[[options]]
.requestShipping
이 true이면:
shippingOptions
에
대하여:
modifiers
멤버가 존재하면:
modifiers
로
둔다.
PaymentDetailsModifier
modifier ∈
modifiers에 대하여:
supportedMethods
에
대해 실행한다. false를 반환하면
업데이트를
중단하고
request와
RangeError
예외를 전달한다.
선택적으로, 결제 방법 식별자가 유효하지 않음을 개발자에게 알린다.
total
멤버가 존재하면:
total
.amount
.
예외가 발생하면
업데이트를 중단하고
request와 해당 예외를 전달한다.
additionalDisplayItems
멤버가 modifier에 존재하면, 각
PaymentItem
item ∈
modifier.additionalDisplayItems
에
대하여:
amount
.
예외가 발생하면
업데이트를 중단하고
request와 해당 예외를 전달한다.
data
멤버가 없으면 serializedData를 null로 둔다.
그렇지 않으면 직렬화를
통해
modifier.data
를
JSON 문자열로 변환한 결과를 serializedData로 둔다.
예외가 발생하면
업데이트를
중단하고
request와 해당 예외를 전달한다.
data
멤버를 제거한다.
paymentMethodErrors
멤버가 존재하고 identifier가 null이 아니면:
paymentMethodErrors
를
IDL 값으로 변환한다.
paymentMethodErrors
를
사용하여 오류를 표시하는 것이 SHOULD이다.
PaymentRequest
를
업데이트한다:
total
멤버가
존재하면:
[[details]]
.total
을
details.total
로
설정한다.
displayItems
멤버가 존재하면:
[[details]]
.displayItems
을
details.displayItems
로
설정한다.
shippingOptions
멤버가 존재하고,
request.[[options]]
.requestShipping
이 true이면:
[[details]]
.shippingOptions
을
shippingOptions로 설정한다.
shippingOption
속성 값을
selectedShippingOption으로 설정한다.
modifiers
멤버가 존재하면:
[[details]]
.modifiers
을
details.modifiers
로
설정한다.
[[serializedModifierData]]
를
serializedModifierData로 설정한다.
만약
request.[[options]]
.requestShipping
이 true이고,
request.[[details]]
.shippingOptions
가
비어 있다면, 이는 개발자가 현재 선택된 배송 주소(즉,
request의
shippingAddress
로
주어진)에 대해 유효한 배송 옵션이 없음을 나타낸다.
이 경우, 사용자 에이전트는 이를 나타내는 오류를 표시하는 것이
SHOULD이며, 현재 선택된 배송 주소가 어떤 방식으로든 유효하지 않음을
표시할 수 MAY 있다.
사용자 에이전트는
error
멤버가
details에 존재한다면 이를 사용하여
해당 주소에 유효한 배송 옵션이 없는 이유에 대한 추가 정보를 제공하는 것이
SHOULD이다.
또한,
details["shippingAddressErrors
"]
멤버가 존재한다면, 사용자 에이전트는 배송 주소의 오류가 있는 각 필드에 대해
구체적인 오류를 표시하는 것이 SHOULD이다. 이는
AddressErrors
의
각 존재하는 멤버를 표시된 사용자 인터페이스 내의 해당 입력 필드에 매칭하여 수행한다.
마찬가지로, details["payerErrors
"] 멤버가 존재하고
request.[[options]]
의
requestPayerName
,
requestPayerEmail
,
또는
requestPayerPhone
가 true이면,
오류가 있는 각 필드에 대해 구체적인 오류를 표시한다.
이와 같이,
details.paymentMethodErrors
가
존재한다면, 해당 결제 방법의 오류가 있는 각 입력 필드에 대해
구체적인 오류를 표시한다.
[[updating]]
을 false로 설정한다.
PaymentRequest
request와
exception
exception으로
업데이트를 중단하려면:
[[state]]
를
"closed"로 설정한다.
[[response]]
로 둔다.
[[complete]]
를
true로 설정한다.
[[retryPromise]]
는
null이 아니다.
[[retryPromise]]
를
exception으로 거부(reject)한다.
[[acceptPromise]]
를
exception으로 거부(reject)한다.
[[updating]]
을 false로 설정한다.
업데이트를 중단은 제공된 detailsPromise가 거부되거나, 이행 값이 유효하지 않은 데이터를 포함하는 등 결제 요청을 업데이트하는 동안 치명적인 오류가 발생했을 때 실행된다. 이는 개발자가 변경 이벤트를 성공적으로 처리하지 못했기 때문에 결제 요청이 불일치 상태로 남을 가능성이 있다.
따라서, PaymentRequest
는
"closed" 상태로 전환된다. 오류는
[[acceptPromise]]
의
거부를 통해 개발자에게 전달되며,
즉, show
()
가 반환한 프로미스가
거부된다.
마찬가지로, 업데이트 중단이
retry
()
중에 발생하면
[[retryPromise]]
는
거부되고, 해당
PaymentResponse
의
[[complete]]
internal
slot이 true로 설정되어(즉, 더 이상 사용할 수 없다).
이 절은 비규범적입니다.
사용자가 의도치 않게 민감한 자격 증명을 특정 출처에 공유하지 않도록 돕기 위해, 이 API는 PaymentRequest의
show
()
메서드가 관련
Window
에 일시적 활성화
(예: 클릭 또는 누르기)을 보유한 동안 호출되도록 요구합니다.
혼란스러운 사용자 경험을 피하기 위해, 본 명세는
show
()
메서드를 통해 한 번에 하나만 표시하도록
사용자 에이전트를 제한합니다. 추가로, 사용자 에이전트는 페이지가
show
()
를 호출하는 빈도를 제한할 수 있습니다.
이 절은 비규범적입니다.
본 명세에서 정의한 API는 보안 컨텍스트에서만 노출됩니다. 자세한 내용은 Secure Contexts 명세를 참조하십시오. 실제로 이는 이 API가 HTTPS를 통해서만 사용 가능함을 의미합니다. 이는 결제 방식 데이터(예: 신용카드 번호)가 평문으로 전송되는 가능성을 제한하기 위함입니다.
이 절은 비규범적입니다.
가맹점과 기타 수취인이 체크아웃 및 기타 전자상거래 활동을 결제 서비스 제공자에게 위임하기 위해
iframe을
사용하는 것은 일반적입니다.
이 API는 [HTML]의
allow
속성을 통해 수취인 승인 교차 출처 iframe을 지원합니다.
결제 처리기는
iframe을
호스팅하는 출처와
해당 iframe
콘텐츠의 출처(여기에서
PaymentRequest
가 시작됨)에 모두 접근할 수 있습니다.
이 절은 비규범적입니다.
PaymentRequest
API는
데이터 필드의 암호화를 직접 지원하지 않습니다. 개별
결제 방법은
암호화된 데이터 지원을 포함하도록 선택할 수 있지만, 모든
결제 방법에 이를 의무화하지는 않습니다.
이 절은 비규범적입니다.
보안상의 이유로, 사용자 에이전트는
show
()
및
canMakePayment
()
에서의
매칭을 URL
결제 방법 식별자와 동일한
origin의
결제 처리기로 제한할 수 있습니다.
결제 방법 소유자는 결제 방법을 위해 수집된 사용자 데이터가 어떻게 사용될지에 대한 개인정보 보호정책을 수립합니다. Payment Request API는 데이터가 거래 완료 및 이 API와 관련된 사용자 경험의 목적에 사용될 것이라는 분명한 기대치를 설정합니다. 결제 수취인은 모든 데이터 사용이 결제 방법 정책을 준수하도록 보장할 책임이 있습니다. 거래 완료를 넘어서는 허용된 사용이 있는 경우, 수취인은 그 사용을 사용자에게 명확히 전달해야 합니다.
사용자 에이전트는 사용자 동의 없이 (예: 배송 주소)와 같은 사용자 정보를 개발자와 공유해서는 안 됩니다.
특히, PaymentMethodData
의
data
및
PaymentResponse
의
details
멤버는 임의의 데이터 교환을 허용합니다.
기존 결제 방법에서 사용되는 다양한 데이터 모델을 고려할 때, 이 API에서 데이터의 특정 형식을 규정하면
유용성이 제한됩니다. details
멤버는
웹 기반(Payment Handler API에 의해 정의됨) 또는
독점적인 결제 처리기에서 온 데이터를 담습니다. 사용자 에이전트는 적절한 사용자 동의 메커니즘(예: 거래 당사자에 대한 인지와
데이터 공유 의사 표시 메커니즘)을 포함하지 않는 결제 처리기를 지원해서는 안 됩니다.
사용자
에이전트는
displayItems
멤버 또는
additionalDisplayItems
멤버의 값을 거래 완료를 용이하게 하는 목적 외의 어떤 목적으로도
공유해서는 안 됩니다.
PaymentMethodChangeEvent
는 수취인이
선택된 결제 방법에 특정한 정보에 기반하여 표시된 총액을
업데이트할 수 있게 합니다. 예를 들어, 선택된
결제 방법과 연관된 청구지 주소는 세금 계산(예: VAT)에 영향을 줄 수 있으며,
지불자가 거래를 완료하기 전에 사용자 인터페이스가 총액을 정확히 표시하는 것이 바람직합니다.
동시에, 결제 완료 이전에는 가능한 한 적은 정보를 공유하는 것이 바람직합니다.
따라서, 결제 방법이
사용자가 결제 방법을 변경할 때의 단계를 정의하는 경우,
PaymentMethodChangeEvent
의
methodDetails
속성을 통해
공유되는 데이터를 최소화하는 것이 중요합니다. 공유 데이터 최소화에 대한 요구사항과 접근 방식은
결제 방법에 따라 달라질 수 있으며 다음을 포함할 수 있습니다:
shippingAddress
에서 마스킹하기 위해
"redactList"를 사용합니다.
PaymentResponse
.details로 반환)에서
제외/포함할 특정 요소를 식별하는 지시사항 지원. 수취인은 이러한 지시사항을
PaymentMethodData
.data를 통해
제공하여,
현재 API를 변경하지 않고도 결제 방법 정의가 발전할 수 있게 할 수 있습니다.
사용자에게 프라이버시 민감 정보의 공유가 명백하지 않을 수 있는 경우(예: 결제 방법 변경 시), 사용자 에이전트가 어떤 정보가 상인과 공유되는지 정확히 사용자에게 알리도록 하는 것이 권고됩니다.
canMakePayment
()
메서드는 다양한 결제 방법에 대한 기능 감지를 제공합니다. 향후 다수의 결제 방법이 사용 가능해지는 경우,
이는 지문 채취 벡터가 될 수 있습니다. 사용자 에이전트는 이 메서드의 남용으로부터 사용자를 보호할 것으로 기대됩니다.
예를 들어, 사용자 에이전트는 다음과 같이 사용자 지문 채취를 줄일 수 있습니다:
속도 제한을 위해 사용자 에이전트는 반복 호출을 다음 기준으로 살펴볼 수 있습니다:
iframe
또는 팝업 창의 origin.
이러한 속도 제한 기법은 반복 호출과 연관된 비용을 증가시키는 것을 목표로 합니다. 이는 여러 등록 가능 도메인을 관리하는 비용이거나, 여러 창(탭 또는 팝업)을 여는 사용자 경험상의 마찰일 수 있습니다.
사용자 에이전트가
show
()
메서드의 일부로 사용자 활성화를 요구하지
않는 경우,
추가적인 보안 완화를 고려해야 합니다. 사용자 활성화를 요구하지 않으면, 사용자가 페이지와 즉시 상호작용하지 않고도
Payment Request UI를 시작할 수 있게 되어 스팸 및 클릭재킹 공격의 위험이 증가합니다.
스팸을 완화하기 위해, 사용자 에이전트는 특정 임계값 이후 사용자 활성화 요구를 강제할 수 있습니다. 예를 들어, 현재 페이지에서 사용자 활성화 없이 이미 Payment Request UI가 표시된 이후와 같은 경우입니다. 클릭재킹 공격을 완화하기 위해, 사용자 에이전트는 대화 상자가 표시된 직후의 클릭을 무시하는 시간 임계값을 구현할 수 있습니다.
또 다른 관련 완화책은
show
()
의 6단계에 존재하며,
사용자 상호작용을 시작하려면 문서가 가시 상태여야 합니다.
이 절은 비규범적입니다.
Payment Request API의 사용자 대상 측면에 대해, 구현체는 폼 컨트롤과 기타 입력 방식들을 통해 플랫폼 접근성 API와 통합합니다. 또한 합계(total), 배송 주소, 연락처 정보의 이해 가능성을 높이기 위해, 구현체는 시스템 규약에 따라 데이터를 서식화합니다.
이 명세는 여러 다른 기반 명세에 의존합니다.
비규범적으로 표시된 절들뿐 아니라, 이 명세의 모든 작성 가이드라인, 도표, 예제, 그리고 노트는 비규범적입니다. 그 외의 모든 내용은 규범적입니다.
이 문서에서 MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, SHOULD, SHOULD NOT 키워드는 BCP 14 [RFC2119] [RFC8174]에 설명된 대로, 그리고 여기에서와 같이 전부 대문자로 나타날 때에만 해석되어야 합니다.
이 명세에 대한 적합성을 주장할 수 있는 제품 클래스는 오직 user agent뿐입니다.
이 명세는 주로 웹 브라우저를 대상으로 하지만, 다른 소프트웨어도 이 명세를 적합하게 구현하는 것이 가능할 수 있습니다.
사용자 에이전트는 최종 결과가 명세의 알고리즘으로 얻어지는 결과와 구별할 수 없는 한, 이 명세에 제시된 알고리즘을 원하는 방식으로 MAY 구현할 수 있습니다.
사용자 에이전트는 서비스 거부 공격 방지, 메모리 고갈 방지, 또는 플랫폼별 제약 회피 등을 위해,
원래 제한되지 않은 입력에 대해 구현체별 한계를 MAY 부과할 수 있습니다.
입력이 구현체별 한계를 초과하는 경우, 사용자 에이전트는 MUST
예외를 던지거나(또는 프로미스 문맥에서는 거부하여) TypeError
로 처리해야 하며,
특정 입력이 어떻게 구현체별 한계를 초과했는지 개발자에게 선택적으로 알릴 수 있습니다.
WebIDL[SecureContext, Exposed=Window]
interface PaymentRequest
: EventTarget {
constructor
(
sequence<PaymentMethodData
> methodData,
PaymentDetailsInit
details,
optional PaymentOptions
options = {}
);
[NewObject]
Promise<PaymentResponse
> show
(optional Promise<PaymentDetailsUpdate
> detailsPromise);
[NewObject]
Promise<undefined> abort
();
[NewObject]
Promise<boolean> canMakePayment
();
readonly attribute DOMString id
;
readonly attribute ContactAddress? shippingAddress
;
readonly attribute DOMString? shippingOption
;
readonly attribute PaymentShippingType
? shippingType
;
attribute EventHandler onshippingaddresschange
;
attribute EventHandler onshippingoptionchange
;
attribute EventHandler onpaymentmethodchange
;
};
dictionary PaymentMethodData
{
required DOMString supportedMethods
;
object data
;
};
dictionary PaymentCurrencyAmount
{
required DOMString currency
;
required DOMString value
;
};
dictionary PaymentDetailsBase
{
sequence<PaymentItem
> displayItems
;
sequence<PaymentShippingOption
> shippingOptions
;
sequence<PaymentDetailsModifier
> modifiers
;
};
dictionary PaymentDetailsInit
: PaymentDetailsBase
{
DOMString id
;
required PaymentItem
total
;
};
dictionary PaymentDetailsUpdate
: PaymentDetailsBase
{
DOMString error
;
PaymentItem
total
;
AddressErrors
shippingAddressErrors
;
PayerErrors
payerErrors
;
object paymentMethodErrors
;
};
dictionary PaymentDetailsModifier
{
required DOMString supportedMethods
;
PaymentItem
total
;
sequence<PaymentItem
> additionalDisplayItems
;
object data
;
};
enum PaymentShippingType
{
"shipping
",
"delivery
",
"pickup
"
};
dictionary PaymentOptions
{
boolean requestPayerName
= false;
boolean requestBillingAddress
= false;
boolean requestPayerEmail
= false;
boolean requestPayerPhone
= false;
boolean requestShipping
= false;
PaymentShippingType
shippingType
= "shipping";
};
dictionary PaymentItem
{
required DOMString label
;
required PaymentCurrencyAmount
amount
;
boolean pending
= false;
};
dictionary PaymentCompleteDetails
{
object? data
= null;
};
enum PaymentComplete
{
"fail
",
"success
",
"unknown
"
};
dictionary PaymentShippingOption
{
required DOMString id
;
required DOMString label
;
required PaymentCurrencyAmount
amount
;
boolean selected
= false;
};
[SecureContext, Exposed=Window]
interface PaymentResponse
: EventTarget {
[Default] object toJSON();
readonly attribute DOMString requestId
;
readonly attribute DOMString methodName
;
readonly attribute object details
;
readonly attribute ContactAddress? shippingAddress
;
readonly attribute DOMString? shippingOption
;
readonly attribute DOMString? payerName
;
readonly attribute DOMString? payerEmail
;
readonly attribute DOMString? payerPhone
;
[NewObject]
Promise<undefined> complete
(
optional PaymentComplete
result = "unknown",
optional PaymentCompleteDetails
details = {}
);
[NewObject]
Promise<undefined> retry
(optional PaymentValidationErrors
errorFields = {});
attribute EventHandler onpayerdetailchange
;
};
dictionary PaymentValidationErrors
{
PayerErrors
payer
;
AddressErrors
shippingAddress
;
DOMString error
;
object paymentMethod
;
};
dictionary PayerErrors
{
DOMString email
;
DOMString name
;
DOMString phone
;
};
dictionary AddressErrors
{
DOMString addressLine
;
DOMString city
;
DOMString country
;
DOMString dependentLocality
;
DOMString organization
;
DOMString phone
;
DOMString postalCode
;
DOMString recipient
;
DOMString region
;
DOMString sortingCode
;
};
[SecureContext, Exposed=Window]
interface PaymentMethodChangeEvent
: PaymentRequestUpdateEvent
{
constructor
(DOMString type, optional PaymentMethodChangeEventInit
eventInitDict = {});
readonly attribute DOMString methodName
;
readonly attribute object? methodDetails
;
};
dictionary PaymentMethodChangeEventInit
: PaymentRequestUpdateEventInit
{
DOMString methodName
= "";
object? methodDetails
= null;
};
[SecureContext, Exposed=Window]
interface PaymentRequestUpdateEvent
: Event {
constructor
(DOMString type, optional PaymentRequestUpdateEventInit
eventInitDict = {});
undefined updateWith
(Promise<PaymentDetailsUpdate
> detailsPromise);
};
dictionary PaymentRequestUpdateEventInit
: EventInit {};
이 명세는 이전에 웹 플랫폼 인큐베이터 커뮤니티 그룹에서 발행한 보고서로부터 파생되었습니다.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
CR2 이후 현재까지의 변경 사항:
CR1과 CR2 사이의 변경 사항: