WICG / webmonetization

Proposed Web Monetization standard
https://webmonetization.org
Other
441 stars 150 forks source link

Decouple payments from session #46

Open wilsonianb opened 4 years ago

wilsonianb commented 4 years ago

https://github.com/interledger/webmonetization.org/issues/45 introduces the idea of web monetization payments that are decoupled from a particular session on a website. The website is pointed to a resource at the receiver (via the provider id) where the website can verify that a payment has been received. However, the payment(s) could have happened at any point in time, not necessarily during the current session.

This brings into question the necessity of the current monetizationstart and monetizationprogress events. Why does a website need to know when in-session payments have started and at what increments and amounts they are happening if (a) there’s more than enough already paid to the website to unlock content and (b) the in-session paid amounts can be used to fund unlocking content in future sessions? They could help inform payment verification retry logic if there wasn’t a sufficient existing paid amount. However, the events themselves aren’t guaranteed to represent actual payments, so a website could just retry at a frequency of its own choosing.

If we were to determine the events aren’t needed, web monetization could be reduced to the following:

  1. The website creates a PaymentRequest when the page loads with the monetization method and payment pointer. The amount could be zero since it doesn’t matter.
  2. The single PaymentRequest event is handled by a registered monetization payment handler, which both determines how much to pay and triggers payments (potentially throughout the entire session).
  3. The payment handler returns a PaymentResponse (either immediately or after starting payment, perhaps depending on if there’s a previously paid amount), which includes the monetization/provider ID (and JWT authorizing the user to be able to spend against the provider’s paid amount).
  4. The website can spend against the paid amount for the ID at the receiver to unlock content throughout the session. If payment verification fails, the website could optionally create a new PaymentRequest with the amount it is attempting to charge. (The subsequent PaymentResponse would be as useful for retrying as monetizationprogress is today.)

If we were to replace websites' monetization meta/link tag with the PaymentRequest, then I think web monetization could be fully supported by the PaymentRequest and PaymentHandler APIs without needing any additional functionality within browsers.

sharafian commented 4 years ago

This brings into question the necessity of the current monetizationstart and monetizationprogress events. Why does a website need to know when in-session payments have started and at what increments and amounts they are happening if (a) there’s more than enough already paid to the website to unlock content and (b) the in-session paid amounts can be used to fund unlocking content in future sessions?

The events on the frontend are also useful for leveraging WM when there's not a server-side component. Hiding banner ads, for instance, really shouldn't require a call to the backend because it's purely a frontend concern.

The single PaymentRequest event is handled by a registered monetization payment handler, which both determines how much to pay and triggers payments (potentially throughout the entire session).

@adrianhopebailie do you know how possible this is? The service worker would have to stay around for a long time working in the background, and it would also need to detect page events / page state. i.e. if the page gets backgrounded, the payment handler would have to stop paying and then get notified when the page gets foregrounded.

I think this is probably the largest barrier for this idea working

If we were to replace websites' monetization meta/link tag with the PaymentRequest, then I think web monetization could be fully supported by the PaymentRequest and PaymentHandler APIs without needing any additional functionality within browsers.

It would be really awesome to solve WM with existing APIs like this.

It's nice to have a declarative API too (for things like scraping, noscript, amp, etc.), but maybe it's possible we could make a standard way of 'translating' a meta tag into a series of PaymentRequest calls. But trading off declarative API for standard browser support would be worth it

adrianhopebailie commented 4 years ago

@wilsonianb this is how I had envisioned us doing an imperative API for WM almost exactly.

What I think we should consider is simply using the payment handler as a way to create the session and start paying and them return control back to the website via the PR API.

My idea was to extend the PaymentResponse object but since then we've added the retry method which could be used.

The flow would be:

  1. Website calls PR API with some parameters that make it clear this is WM (special payment method or something) so that the browser only invokes the PH if it can do so with no UI
  2. The browser invokes the PH through the PaymentRequestEvent (this already has a unique ID (UUID) which is equivalent to the session id we are using today.
  3. The PH from the provider connects to the provider and instructs it to open a STREAM to the payment pointer provided in the PR (paid using an anonymous privacy pass token).
  4. Once the provider acks the request to let the PH know that the STREAM is open and is being paid the PH responds to the PaymentRequestEvent
  5. This causes the Promise returned when calling PR.show() to resolve with a PaymentResponse object.
  6. If the streaming stops (the token used has been spent) then the website calls PaymentResponse.retry() which invokes the PH again and it instructs the provider to send more.

The response from the provider could indicate the amount of time that it will pay for until it requires a refresh so the website could proactively call retry and not wait for the stream to stop sending.

sidvishnoi commented 3 years ago

@adrianhopebailie Do we want to give website the control of payments (specifically the ask for more/continue payment parts)? It aligns well with the PaymentRequest API, but I think it's opposite of how we've seen WM until now, in which the website passively listens to monetizationProgress. Maybe we're looking at two approaches for WM: a user tips website (hoping) for something in return, vs the website asks user x amount to have certain feature?

adrianhopebailie commented 3 years ago

@sidvishnoi I think there are two distinct APIs:

WM is a declarative API where a website declares a “way you can pay me” (i.e. a Payment Pointer). The website then may or may not respond to events emitted from the DOM that indicate it has received a payment. These payments could be small regular payments (streams) or larger one-off payments that the user initiates from the extension but the API is the same, each event is a receipt for a payment.

Using the same underlying payment rail (Interledger) we can use PaymentRequest to request explicit payments from the user for IAP (in-app payment) scenarios or tip buttons rendered by the website.

marcoscaceres commented 2 years ago

Closing as answered.