Update your monetization scripts

Purpose
This page describes what you should do to upgrade your scripts from the old to the new WM spec. It is linked to by the extension's debugger if it encounters a meta tag.

You likely come to this page because the Coil extension debugger gave a warning. Here we explain what this warning means and what you should do.

In 2022 a new version of the Web Monetization specification and API was created, and the Coil extension will eventually cease to support the old API. If you make the changes detailed below you're ready for the new version.

meta to link

The old Web Monetization specification uses a <meta> tag to create a payment pointer, like this:

<meta name="monetization" content="$url.of.server/someID">

You should replace this by a <link> tag, like this:

<link rel="monetization" href="https://url.of.server/someID">

The $ part of the old payment pointer should be replaced by https://.

If your payment pointer does not end in a slash / you have to add /.well-known/pay to it. So this

<meta name="monetization" content="$url.of.server">

becomes this

<link rel="monetization" href="https://url.of.server/.well-known/pay">

It is possible to have multiple <link> tags in your HTML, and they do not need to be in the <head>, either. See example scripts for examples of how to use this.

document.monetization

The document.monetization object has been removed. You should remove all references to it from your code. In practice this means two things.

Feature detection

First, you may be using a feature detection like this:

if (document.monetization) {
	// your web monetization script
}

This will no longer work; no browser will support document.monetization and your code will no longer run. Instead, check if the browser understands a <link rel="monetization"> like this:

let testLink = document.querySelector('link[rel=monetization]')
if (testLink && testLink.relList.supports("monetization")) {
	// your web monetization script
}

Try to take a <link rel="monetization"> (it doesn't matter which one), and first check if it is present at all, and then if its relList property, which contains all possible values of the rel attribute, recognizes monetization (i.e. if the browser knows what to do with such a link). If both are the case you're good to go and can run your script.

Defining events

Second, monetization events used to fire on document.monetization. They no longer do so; instead they fire on all individual <link> tags.

In the old API you'd do something like this:

document.monetization.addEventListener('monetizationprogress',function() {
	// your monetization script
});

This should be replaced by

let link = [the link tag you want to listen to]
link.addEventListener('monetization',function() {
	// your monetization script
});

In addition to being fired on all <link> tags, the event also has a new name. So let's study events.

Events

The old API contained four monetization events: monetizationpending, monetizationstart, monetizationstop, and monetizationprogress. The first three have been removed entirely, while monetizationprogress changed to monetization.

Switching from monetizationprogress to monetization is easy: just change the event name and you're done.

The other three events cannot be replaced simply; these three events were removed because they don't add a lot of useful functionality. First wonder if you need them at all, or if you can achieve your goal in a different way. If you really need them you should write a custom script. You can find some information and inspiration in the example scripts.

Event properties

In the old API the event had six custom event properties. They were all defined on event.detail. The new API moved them directly to the event, and removed one property.

For instance, in the old API this was the way to find out how much money a single Interledger package contained:

document.monetization.addEventListener('monetizationprogress',function(e) {
	let amt = e.detail.amount;
	let scale = e.detail.assetScale;
	let code = e.detail.assetCode;
	let amount = amt * Math.pow(10,-scale);
	let printableAmount = code + ' ' + amount;
	// do something with printableAmount
});

The three properties amount, assetScale, and assetCode are unchanged, but they are moved to the event object itself. So the new API requires this code:

let link = [the link tag you want to listen to]
link.addEventListener('monetization',function(e) {
	let amt = e.amount;
	let scale = e.assetScale;
	let code = e.assetCode;
	let amount = amt * Math.pow(10,-scale);
	let printableAmount = code + ' ' + amount;
	// do something with printableAmount
});
Old API New API Remarks
amount amount Integer with the amount in this Interledger package
assetCode assetCode The three-letter code describing the currency; e.g. USD, EUR
assetScale assetScale The scale of the amount (see example script above)
paymentPointer paymentPointer The <link> tag's payment pointer.
receipt receipt The base-64 encoded Interledger Stream receipt the browser received
requestID - No longer available