Web Monetization allows websites to automatically receive payments from users, facilitated by the user agent and a user's preferred monetization provider.
This specification is a work in progress within the community on the best shape it should take. Please see the documentation for more info.
The specification reflects the desired end-state of the Web Monetization APIs as currently anticipated and agreed to between the contributors. The specification is being prepared here, in this format, to collect the input of the Web community and prepare the work to ultimately follow the W3C standards track should it have the necessary support to do so.
For the most accurate reflection of the APIs that have been implemented by providers see the API documentation.
Call {{DOMTokenList/supports()}} on a [^link^] element’s {{HTMLLinkElement/relList}} passing the `"monetization"` keyword to check if Web Monetization is supported by the user agent.
The {{MonetizationEvent}} DOM events provide information such as the amount sent, the currency of the payment, and a link to the incoming payment at the [=monetization receiver=] which can be used to verify the receipt of payment. As in the previous example above, these events are dispatched to [^link^] elements and bubble up the DOM tree.
To listen for {{MonetizationEvent}} events, an [=event listener=] needs to be added to the relevant [^link^] element (or to one of its ancestors) via JavaScript:
The {{MonetizationEvent}}'s {{MonetizationEvent/incomingPayment}} attribute is a URL that can be used to verify the payment at the [=monetization receiver=].
In most cases requests to the {{MonetizationEvent/incomingPayment}} URL will need to be authenticated as they fetch sensitive details such as the `receivedAmount`. The specifics of this authentication are agreed by the website and the [=monetization receiver=] when setting up the receiving account.
Below is a hypothetical naive verification method that will make a request to the {{MonetizationEvent/incomingPayment}} URL and simply return the results. For simplicity it has no logic for authenticating the request.
A more sophisticated implementation SHOULD track the `receivedAmount` property and ensure it is increasing after each {{MonetizationEvent}} to verify that a new payment has been received.
The following example shows how to monetize various types of media using different [=wallet addresses=].
The `monetization` keyword indicates a [=wallet address=] used to monetize the document. It indicates that some aspect of the document is [=monetized=].
The `monetization` keyword MAY be used with [^link^] elements. This keyword creates an [=external resource link=]. This keyword is body-ok.
A user agent MUST NOT delay the load event for this link type.
A user agent MAY restrict the number of concurrent [=payment sessions=] it simultaneously supports.
The default type for resources given by the `monetization` keyword is `application/json`.
A [^link^] element with this link type has an associated payment session, a [=payment session=] or null. It is initially null.
The appropriate times to fetch and process this type of link are:
When the [=external resource link=] is created on a [^link^] element that is already [=browsing-context connected=].
When the [=external resource link=]'s [^link^] element becomes [=browsing-context connected=].
When the [^link/href^] attribute of the [^link^] element of an [=external resource link=] that is already [=browsing-context connected=] is changed.
When the [^link/disabled^] attribute of the [^link^] element of an [=external resource link=] that is already [=browsing-context connected=] is set, changed, or removed.
When the [^link/crossorigin^] attribute of the [^link^] element of an [=external resource link=] that is already [=browsing-context connected=] is set, changed, or removed.
When the [^link/type^] attribute of the [^link^] element of an [=external resource link=] that is already [=browsing-context connected=] is set or changed to a value that does not or no longer matches the Content-Type metadata of the previous obtained external resource, if any.
When the [^link/type^] attribute of the [^link^] element of an [=external resource link=] that is already [=browsing-context connected=], but was previously not obtained due to the [^link/type^] attribute specifying an unsupported type, is set, removed, or changed.
The fetch and process the linked resource algorithm for this type, given a [^link^] element |element|, is as follows:
The linked resource fetch setup steps for this type of linked resource, given a [^link^] element |element:HTMLLinkElement| and [=request=] |request|, are:
If |element|'s [^link/disabled^] attribute is set, return false.
If |element|'s [=Node/node document|node document=] is not [=allowed to use=] the "monetization" feature, return false.
Set |request|'s [=request/initiator=] to "`document`".
Set |request|'s [=request/destination=] to "`monetization`".
Set |request|'s [=request/mode=] to "`cors`".
Set |request|'s [=request/credentials mode=] to the [=CORS settings attribute credentials mode=] for |element|'s [^link/crossorigin^] content attribute.
Return true.
To process this type of linked resource given a [^link^] element |element|, boolean |success|, and [=response=] |response|:
If, since the resource in question was fetched, it has become appropriate to fetch it again, return.
If |response|'s status is not an OK status, then set |success| to false.
Otherwise, if |response|'s Content-Type metadata is not `application/json`, then set |success| to false.
If the user agent has exhausted the number of allowed [=payment sessions=], set |success| to false.
When a [^link^] element stops creating a "monetization" [=external resource link=], or stops being [=browsing-context connected=], a user agent MUST stop its [=associated payment session=], if any, and set it to null.
This specification patches the [[HTML]] specification's [^link^] element's `disabled` attribute:
The `disabled` attribute is a boolean attribute that is used with the `stylesheet` or `monetization` link type. The attribute must only be specified on [^link^] elements that have a [^link/rel^] attribute that contains the `stylesheet` or `monetization` keyword.
The {{GlobalEventHandlers}} interface is defined in [[HTML]].
partial interface mixin GlobalEventHandlers {
attribute EventHandler onmonetization;
};
The attribute MUST be an [=event handler IDL attribute=] and [=event handler content attribute=] for the {{monetization}} event supported by all [=element=]s, {{Document}} objects, and {{Window}} objects. The user agent uses it to notify that a payment has been [=initiated=] for a [=monetized=] [^link^].
monetization event
When the [=payment session=] has [=initiated=] a |payment| with a non-zero amount, perform the following steps:
The following [=task source=] is defined by this specification.
The `MonetizationCurrencyAmount` interface maps directly to the {{PaymentCurrencyAmount}} dictionary.
[SecureContext, Exposed=Window]
interface MonetizationCurrencyAmount {
readonly attribute DOMString currency;
readonly attribute DOMString value;
};
The currency of the MonetizationCurrencyAmount. The default is an ISO 4217 three-letter alphabetic code; see the definition of the `currency` member of {{PaymentCurrencyAmount}} in [[payment-request]] for details.
The amount of the MonetizationAmount. See the definition of the `value` member of {{PaymentCurrencyAmount}} in [[payment-request]] for details.
To create a monetization currency amount, given a {{PaymentCurrencyAmount}} |paymentAmount| and a [=ECMAScript/realm=] |realm|, run the following steps:
[SecureContext, Exposed=Window]
interface MonetizationEvent : Event {
constructor(DOMString type, MonetizationEventInit eventInitDict);
readonly attribute MonetizationCurrencyAmount amountSent;
readonly attribute USVString? incomingPayment;
readonly attribute USVString walletAddress;
// Following are deprecated
readonly attribute DOMString? amount;
readonly attribute DOMString? assetCode;
readonly attribute octet? assetScale;
readonly attribute DOMString? receipt;
readonly attribute USVString paymentPointer;
};
dictionary MonetizationEventInit : EventInit {
required PaymentCurrencyAmount amountSent;
required USVString? incomingPayment;
required USVString walletAddress;
// Following are deprecated
required DOMString? amount;
required DOMString? assetCode;
required octet? assetScale;
required DOMString? receipt;
required USVString paymentPointer;
};
The [=event constructing steps=] for {{MonetizationEvent}}, given |event| and |eventInitDict|, are:
The {{MonetizationEvent/amount}}, {{MonetizationEvent/assetCode}}, {{MonetizationEvent/assetScale}}, {{MonetizationEvent/paymentPointer}} and {{MonetizationEvent/receipt}} attributes are deprecated.
All [=monetization receivers=] should be migrating from generating a [[[Receipt]]] to supporting incoming payments via [[open-payments]] and will no longer be returning receipts to the browser.
As such the {{MonetizationEvent}} no longer represents an amount received; it represents an amount sent and returns a URL as the {{MonetizationEvent/incomingPayment}} attribute that can be used to determine the amount received.
The amount sent. When getting, returns the {{MonetizationCurrencyAmount}} it was initialized to.
A [=URL=] representing an incoming payment at the [=monetization receiver=]. When getting, returns the value it was initialized with.
A [=URL=] representing the [=wallet address=] the payment was initiated for. When getting, returns the value it was initialized with.
The amount received as reflected in the receipt from the [=monetization receiver=]. When getting, returns the value it was initialized with.
The three letter asset code identifying the amount's units (e.g., "USD" for US dollars). When getting, returns the value it was initialized with.
The scale of the amount. For example, USD would have an `assetScale` of `2` when denominated in cents. When getting, returns the value it was initialized with.
`null` or a base64-encoded [[[Receipt]]] issued by the [=monetization receiver=] to the [=monetization provider=] as proof of the total amount received in the [=payment session=]. When getting, returns the value it was initialized with.
A [=URL=] representing the [=wallet address=] the payment was initiated for. When getting, returns the value it was initialized with.
This specification defines a [=policy-controlled feature=] identified by the string "monetization". Its default allowlist is `'self'`.
The monetization-src directive restricts the URLs from which a [=wallet address=] is loaded. The syntax for the directive's name and value is described by the following ABNF:
directive-name = "monetization-src"
directive-value = serialized-source-list
This directive's pre-request check is as follows:
Given a [=request=] (|request|) and a [=violation/policy=] (|policy|):
This directive's post-request check is as follows:
Given a [=request=] (|request|) and a [=violation/policy=] (|policy|):
This spec patches the [[CSP]] specification's directive fallback list
Given a string |directiveName|:
This spec patches the [[CSP]] specification's effective directive for request
Given a request (|request|):
This spec patches the [[FETCH]] specification's [=destination type=].
A destination type is one of: the empty string,
"audio", "audioworklet",
"document", "embed", "font",
"frame", "iframe", "image",
"json", "manifest",
"monetization", "object",
"paintworklet", "report",
"script", "serviceworker",
"sharedworker", "style",
"track", "video",
"webidentity", "worker", or
"xslt".
It is RECOMMENDED that a user agent provide some UI or indicator that allows the user to know when [=monetization=] is possible and/or when [=monetization=] is occurring. Providing such a UI allows the users to retain control of the monetization process by taking action (e.g., stop or start monetization of a particular site if they wish to do so).
As [=wallet addresses=] are generally provided as a service, a XSS attack could inject malicious [=wallet addresses=] into a page that uses the same service. To mitigate such an attack, it is RECOMMENDED that developers:
Web Monetization is designed to be privacy-preserving: the user agent only shares data with the [=monetization provider=] and the [=monetization receiver=] as they need it.
The [=monetization provider=] only receives what it needs to send a payment: the amount, and the [=wallet address=] to pay. The user agent does not send the URL of the document, or of any other page the user visits, to the [=monetization provider=].
The user agent does not send data about the user to the [=monetization receiver=]. To set up a [=payment session=], it fetches the [=wallet address=] instead.
Unlike [[[Payment-Request]]] and the [[[Payment-Handler]]], which only supports "one-off" payments, Web Monetization provides a [=payment session=] that supports both continuous payments and "one-off" payments.