The Web Monetization specification provides a frictionless payment experience for site owners and site visitors. It deliberately does not provide a user interface; instead, when a web-monetized visitor visits a web-monetized website a transaction takes place automatically. Thus, visitors automatically pay a small sum per time unit to any web-monetized website they visit.
Both visitor and owner must have an account at an Interledger-enabled ledger. Payments will be made from the visitor's to the owner's account. In addition, visitors must be members of a payment provider that arranges for the payments to be sent from their account to the owner's account.
Site owners must add a <link>
tag with a payment pointer to their site that defines a payment end point. When web-monetized visitors are logged in to their payment provider the web monetization implementation (for instance a browser or an extension) will automatically scan for payment pointers and initiate a payment stream from the visitor's account to the defined end point (i.e. the owner's account).
A payment stream typically sends a small amount every second, or any other time unit chosen by the payment provider. Thus, the longer visitors stay on a web-monetized site, the more money the owner receives.
A monetization
event fires each time a payment arrives and that allows site owners to monitor whether payments are being sent, and if so how large they are. This allows owners to tailor the site content to the payments received — for instance by showing premium content only to paying visitors.
Iframes embedded in a web-monetized site can be monetized as well, but only if their allow
attribute contains the value monetization
and the document in the iframe contains a payment pointer. In that case the page in the iframe shares in the monetization stream of the parent page.
<link>
tag<link>
tags with a payment pointer must have the following structure:
<link rel="monetization" href="https://example.com/pay-me">
It must have a rel="monetization"
that declares the <link>
tag is a payment pointer. The href
attribute must contain a link to the actual payment pointer.
The payment pointer is a JSON file that implementations download and read. This file contains Interledger SPSP instructions that allow implementations to connect to the actual payment end point for the payments. If no JSON is found, or the JSON is malformed, the link
element will fire an error
event and no payment stream will be initiated.
An HTML document can contain several <link>
tags, all of which will share in the monetization stream. However, implementations may set a practical maximum to this number.
<link>
tags do not need to be in the <head>
. This, for instance, is a valid payment pointer:
<video src="myvideo.mp4"> <link rel="monetization" href="https://example.com/video/pay"> </video>
Site owners can add a script that plays the video only if the visitor monetizes their site. [Add link to example script, which will do just that.]
Payment pointers will be re-evaluated every time implementations send out an SPSP request. Thus, if a script changes the link's payment pointer or the disabled
attribute, this change will be reflected in the next iteration of the payment stream. The stream will be diverted if the <link>
tag contains a new payment pointer, and it will stop if disabled
is true
or a new payment pointer causes an error. Implementations will continue to try to initiate a stream, so once the problem is resolved the payment stream will re-start.
The monetization event interface is added to each monetization link
element and defines a single monetization
event that fires each time an Interledger receipt containing a proof of payment reaches the browser.
let monetizationLink = document.querySelector('link[rel=monetization]'); monetizationLink.onmonetization = adjustContent; // or monetizationLink.addEventListener('monetization',adjustContent); function adjustContent() { // show or hide content based on the visitor's monetization status }
The monetization
event bubbles up.
The monetization
event’s detail
has the following properties:
amount
assetCode
assetScale
receipt
paymentPointer
<link>
tag's payment pointer.amount
is an integer. assetScale
gives the scale of the amount. For instance, if amount
is 1172 and assetScale
is 5, the receiver received 1172*10^-5 or 0.01172 of whatever currency was defined in assetCode
.
In this simple example the video is web-monetized and starts playing only when a web monetization stream has started. The <link>
tag is embedded in the video for ease of scripting.
<video src="myvideo.mp4" id="myVideo"> <link rel="monetization" href="https://example.com/video/pay"> </video>
A monetization
event listener is added to the video
element. Once the first payment of the web monetization stream arrives the event fires, bubbles up to the video;
, and the event handler adds controls to the video and starts playing it.
let monetizedItem = document.querySelector('#myVideo'); monetizedItem.addEventListener('monetization',function(e){ this.controls = true; this.play(); },{once:true})
The following example keeps track of how much money the video received in the current session, i.e. from the last time the visitor loaded or refreshed the page.
let monetizedItem = document.querySelector('#myVideo'); let totalAmount = 0; monetizedItem.addEventListener('monetization',function(e){ let amount = e.amount; let scale = e.assetScale; let currentAmount = amount * 10^-scale; totalAmount += currentAmount; if (totalAmount > 0.002) { // do something, such as starting the video } })
The final example updates the payment pointer by changing the href
attribute of the <link>
tag. The next payment request will go to the account specified by the new pointer.
let newPointer = 'https://example.com/pay-me-more'; let link = document.querySelector('video link'); link.setAttribute('href',newPointer);