Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
HTTP 402: Payment Required (developer.mozilla.org)
224 points by jpomykala on Feb 2, 2020 | hide | past | favorite | 135 comments


I find it interesting that so much of the response here is negative, to the tune of "This shouldn't have been part of the HTTP protocol, it's useless".

From my point of view, a web where this status code works correctly would be very different, and mostly in a good way - so I find having this in the protocol a noble attempt that didn't pan out. But that's not a failure of the design - the reasons 402 is not able to do anything are more political/environmental than technical in nature, having more to do with how the world works, not with how HTTP works.

From the technical point of view, it's very easy to imagine how it could work, for example: The site says 402, with some standardized headers telling my browser the amount and purpose. Browser pops up a dialog to let me confirm (if I want) and choose a payment method from the ones I registered with it. If I confirm, browser resends the request with a "ChargeTo: pay://visa.com/<token>". No special interface needed on the website, no need for me to give credit card info to random websites.

That's a preferable outcome to what we have now. Sure, it didn't end up working that way. But: a) it's hard to predict what'll get traction at the time of protocol design, b) it's never too late for somebody to salvage this status code, like the REST revival did with so many other HTTP status codes that were rarely used.


The W3C Web Payments standard is more or less what you describe.


This is actually used. I get it all the time.

The only thing very interesting about 402 is that it is so close to 400 - meaning some committee must have thought this would be important for the future (of the internet). I guess history didn't pan out this way.

On GCP: https://cloud.google.com/resource-manager/docs/core_errors PAYMENT_REQUIRED (402) dailyLimitExceeded402: A daily budget limit set by the developer has been reached. quotaExceeded402: The requested operation requires more resources than the quota allows. Payment is required to complete the operation. user402: The requested operation requires some kind of payment from the authenticated user.


"meaning some committee must have thought this would be important for the future (of the internet)."

Have a read down the entire standard [1] with an eye to that. There's a number of codes that are useless (some deprecated), and a number of other codes that I feel uncomfortable calling useless, but compared to how the web evolved, certainly aren't working the way the initial designers intended. 406 "Not Acceptable", for instance, is for when the client sent up Accept-* headers that don't match anything the server offers. That's technically usable, but content negotiation ultimately didn't play as big a part of the web as RFC 7231's text suggests the authors thought it would.

There's a lot of response codes squeezed on both sides by the fact that 1. they're too underspecified to be really useful (yes, it's great that you can return 402 payment required, but where is the browser supposed to go from there?) and 2. had they been specified enough to use at the time they were specified, they would have been utterly wrong. I don't think there's any way to square that circle at a standards level.

[1]: https://tools.ietf.org/html/rfc7231#section-6.2


> it's great that you can return 402 payment required, but where is the browser supposed to go from there?

Don't forget the browser is allowed to return a HTML page with the 402 error, telling the browser, user, or other user-agent exactly what to do.

For example the 402 error page could contain a payment form to be filled in, or other instructions to the user.

Or even a button: "Yes I agree to pay $10 to see the article".


The entire point of returning a status code, at least in theory, would be to not simply be practically-semantically indistinguishable from a 200.

In practice, if you try to return a 402 with an HTML page explaining how to pay, you'll quickly revert that because you'll break some percentage of HTTP clients (not browsers, but other ones) that will try to do "something" with 402, even if it's just assuming "well, it's a 4xx so it's basically a 404", and you'll return a 200 for that page. On the one hand, it isn't necessarily that many clients that will blow up, but on the other hand, you'll observe that no clients will be confused by the 200, so the engineering pressures are pretty consistent here, which is why everybody ends up in the same place.

In theory, if you read the standard, you ought to be able to return a 402, and use content-negotiation to decide whether to return it in a human-readable format, or some rich selection of machine-readable formats, and you ought to be able to annotate it with several dimensions of somewhat overlapping information about exactly how to cache it and exactly what conditions should cause the cache to be expired, including some specification of the HTTP-standard authorization techniques available, etc. etc.... in practice, pretty much every individual element in that collection only sorta works, and trying to do all of them at once essentially impossible at scale, and you'll return a 200 page with HTML and expect the client to pick up the pieces, and if you do offer a JSON view, while you may honor the negotiation stuff you'll probably also allow a querystring or form parameter to ask for JSON too because you can't count on the people writing clients to even know what headers are.... and libraries often make them somewhat less convenient to work with than form parameters, since everybody needs those. And you probably won't "content negotiate" at all, but just have entirely separate URLs for your human stuff and your official "REST API", because most people who try to get clever and make your human website URLs also be the "REST API" pretty quickly discover it's not worth the effort.


I'm sorry, but this is a misunderstanding of the web at a very basic level.

    In theory, if you read the standard, you ought 
    to be able to return a 402 [snip]
Every "problem" you just described applies to 404 as well, and everything handles that just fine.

There is absolutely no problem with servers returning 4xx/5xx codes along with some HTML to render.

All the other things you just described, the content negotiation and so on, are highly debatable at best but the important thing to understand is that they're completely orthogonal to whether or not the server has returned some HTML along with the error code.

You are correct in that human readers don't really know/care whether it's a 4xx/5xx code. But that's fine. They're humans, so it's OK for the HTML returned to give them a choice of what to do.

Non-200 response codes are, of course, already massively useful for other bits of code, for RESTful services and otherwise.


> Every "problem" you just described applies to 404 as well, and everything handles that just fine.

I'm not sure what value of everything you're using, but I remember Internet Explorer's 'friendly error messages'. If your html isn't long enough, and that abomination still exists, you'll get Microsoft's 404 instead of your nice and short 404.

I have worked with many embedded http clients that can't reliable return content unless it's from an HTTP 200. I wouldn't write one like that, but you don't always get to pick your platform, and some platforms give you HTTP or nothing, so you can't use TCP and do a better job (or more often, you have much more important platform issues to work around than to roll your own http when the platform one works enough and it's trivial to just return 200 in case the server had something to return to the client)


> If your html isn't long enough, and that abomination still exists, you'll get Microsoft's 404 instead of your nice and short 404.

The most annoying part is that this knowledge was abused to make even the most basic and otherwise-useless 404 pages show up in IE.

Back when this was a thing, I literally saw this happen. I have one of these pages saved, which is how I know - it was a page which just had "Not Found - The requested document was not found on this server." on it (along with the site name), and then a long HTML comment saying 'Unfortunately, Microsoft has added a clever new "feature" to Internet Explorer.' and explaining the comment's existence.

All for a 404 page that gave far less useful information than IE's own 404 page did. If the page had any brand styling on it I might understand, but this was literally a bare-bones, no-styling page with nothing useful on it.


Also many libraries are built by throwing exceptions for non-200 error codes.


No conflict there.

For SOAP stuff, an exception on 4xx/5xx is generally a sensible design.

For human user-agents (ie, web browsers) there's still no conflict. Deciding whether or not to render some HTML is orthogonal to whether or not some other action might be taken. Generally, you do want to present a choice to the user at this point.


Developers are always doing a if curl status > 400 throw error. I keep running into this pattern in external libruaries. Then they throw the error in place. Please stop this and bubble up the error so the user of the lib can decide.


You do know browsers render 404 error pages, right?


Yes. 200, 301, and 404 are top-tier status codes that even the simplest system can't help but handle in some sensible manner. In the second tier you have the necessary support for partial content and basic content negotiation. After that is when it gets a lot more complicated.

The fact that "browsers render 404 pages" won't save you when you try to get "clever", err, I mean, "standards compliant" and serve a complicated HTTP page out on 402. It probably won't confuse browsers, which will probably just render the page and leave the user oblivious a 402 occurred, which is precisely why I included "(not browsers, but other ones)".

Browsers are forced to march together in some semblance of lock step. When you step out into the heterogeneous world programming language APIs, "convenience" code written on top of those APIs, frameworks written on top of that convenience code, internal libraries written on top of those frameworks... yeah... you can't get very many complicated semantics through that sort of pipeline. And that's not a terribly unrealistic pipeline, unfortunately.


If 402 had actually become part of a means to get paid it would have quickly joined that list of top tier codes right behind 200.


Don't forget these popular code. You were probably 301/302ed at least once today. 201 is popular too. In fact you probably have to do something that will give you a 201 before you get your 402.

301 Moved Permanently 302 Found 400 Bad Request 401 Unauthorized 403 Forbidden 404 Not Found 410 Gone 500 Internal Server Error 501 Not Implemented 503 Service Unavailable 550 Permission denied


What you are saying is true; what I was keeping myself confined to are the codes that you have reasonable assurance that the client will actually do something with. A lot of those codes will not cause the client to do anything terribly specific, like "follow a redirect"; it'll just return the content as if it was a 200, and if it's an API, maybe return the request as failed, but that's about it. In the vast majority of cases, clients don't particularly care if they get 400, 401, 403, 404, or indeed, 4xx.

I wonder if there's even a single client in the world that will get a standards-compliant 412 Precondition Failed and try a second request with a different set of conditions. Or indeed do anything sensibly different at all vs. having received a 404. (I specify "standards-compliant" because I'm sure there's plenty of APIs that use 412 for something non-standard.)


And if browsers did something sensible with I'm A Teapot it would "have quickly joined that list of top tier codes right behind 200". So? We have what we have.


Most modern browsers do.


> The HTTP 418 I'm a teapot client error response code indicates that the server refuses to brew coffee because it is a teapot.

I wonder how FF/Chrome would react to this!


By just rendering it: https://httpstat.us/418



I saw dozens of websites with elaborative 404 pages, like including search form, or even returning site search results with context of requested page, splitting URI to keywords. I see how it is implementable with 402 status as well.


That seems reasonable to me. Browsers ended up dealing with 401 and "Basic Auth", in a semi-standard way, for example. "Payment required" isn't substantially different. More complex for sure, but the context shared seems sufficient.


I am totally going to throw a 406 Not Acceptable in production now. Thank you for the idea.

Not sure how I’ll find an excuse, but I have years to plan.

406 Unacceptable would have made it more useful for today’s tumultuous world.


Error 406: Not Acceptable

User address "123 Main st, Scunthorpe" includes unacceptable language.


IME HTTP 406 is not as uncommon as you imply. Ask a Java/JAX-RS service for accept: foo/bar and 406 Not Acceptable is what you'll probably get.


422 Unprocessable Entity is also relatively commonly used in the enterprise Java world for validation errors, despite technically only being for WebDAV


But there's relatively little value in that being an extra code: How often do you encounter systems that do something with the fact that it is 406 and not a generic 400 and e.g. switch their content type? I think that's what the parent is referring to.


> But there's relatively little value in that being an extra code

For the developer of the client, there is value in that it tells you to start your troubleshooting by looking at the "Accept" header. By contrast, a generic 400 doesn't give you that hint; maybe there will be something in the response headers or body to give you that hint, maybe there won't be.


I agree you probably won't find a lot of systems that will automatically "fix" a 406 or 422, or that have an ordered list of more than one media type they are willing to accept in followup requests. OTOH I do think it's useful to be able to convey and log this type of error in a standard way. 406 can be more or less interesting than 400 retrospectively.

Also, isn't HTTP 503 just about the same as 500 as far as your garden variety client is concerned--even if it's technically plausible some client, somewhere, might want to more aggressively seek out a stale cached result for a 503?


503 could still be useful if combined with the Retry-After header but I wonder if any generic client code/library uses it in that way.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Re...


503 is useful for me as a human. If I see a 500 on an internal site I assume they're throwing exceptions; if I see 503 I know the service is gone and I should redeploy.


Yes; the idea behind 406 and the whole content negotiation thing seemed to be that clients and servers would somehow notice they didn't negotiate a common representation and then do "something" sensible in response to that, not that it would be essentially treated no differently from any other 4xx error.

Quite a lot of the web would just ignore the mismatch and serve the resource up anyhow with whatever Content-Type the server wanted, and, honestly, that seems to work OK.

It's not that it may not be an error in some sense, it's that the standard has this rich set of specific errors that seems as if it's coming from some parallel universe where the web evolved much differently. And it's not that there is no overlap with our real universe, it's just that if you read the standard and kind of do a postmodernism-style analysis of what the authors must have thought was important, what you get doesn't much resemble the real-world web of today. Or in the case of HTTP 1.1, even the real world web of the time.


One hypothetical use case I can think of going forward is sites/content that only work with JavaScript enabled, and that you must request with "Accept: application/html" to signal you're willing to execute their code, as opposed to "text/html" to signal you're not specifically going to switch on JavaScript for their trackers, and expect at least basic static content to show up. Of course, "application/html" needs to be registered at IANA first, and then should be used on most of today's aggregator sites.


You'd have to also change all clients to not execute JavaScript in text/html, if you want application/html to have any bite. Another option, perhaps more likely to have an effect, is to have clients with no JavaScript enabled to include a parameter with the accept type, e.g. `text/html;profile=no-js` or some such. Servers that don't recognize the parameter can just ignore it, and servers that do recognize it can serve up a no-js response. Any client that doesn't know this parameter will just functions as normal. No need to invent a new content type.


Also mostly automatically returned by Rails


I think the problem is that "payment required" is an issue that's better dealt with in a layer higher up the protocol stack.

One can simply respond with the appropriate redirection code to a login/signup page (or whatever) when the client attempts to access a page where "payment is require" (just like any other authentication/authorization issue).


That is not what the user would want though.

Getting nothing is adequate when nothing exist. Pretending it was something else is just confusing at best.


I thought Not Acceptable was a counterpart to 202 Accepted, meaning, "we could not accept this request for processing"? I've also seen it used in place of 400, which is definitely a misuse, but overall, I think it's a very unclear label...


Well, you're supposed to read the docs, not just guess from the label. But I agree that they could have done better; maybe "No acceptable response".


>406 "Not Acceptable"

That is fairly amusing considering the sort of nonsensical popularity of that phrase (at least in the US).


It made it into Project Xanadu's 17 rules, so I imagine this was likely in the minds of most people when the internet was starting out.

> 15. Every Xanadu service provider can charge their users at any rate they choose for the storage, retrieval and publishing of documents.

https://en.wikipedia.org/wiki/Project_Xanadu#Original_17_rul...


I use 402 in one of my web applications at the payment step, but it is kind of just arbitrary as I use the accompanying error message on the frontend.


I don't think that was the original intended use.

I believe the intention of this status code was to allow the application to negotiate payment using some not-yet-invented payment technology.

The browser would presumably shell out to some kind of local wallet or bank website to authorize the payment, all in a split second without the user noticing.

What you're describing is the typical paywall type page where a user is asked for payment.


This is a perfectly legit comment but can you please not use a trollish username on HN? It ends up trolling every thread it posts to, and whether they're right to or not, some people are inevitably going to be provoked by it.

If you'd like to change the account name, we'd be happy to help with that at hn@ycombinator.com.

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...


Funny thing is, I wouldn't have noticed the account name if you didn't point it out.


Others would, though. That's the problem with the long tail: it only takes one or two provokeables to end up with an offtopic mess.


Looks like you're the only one provoked by the name, dang.


No, someone emailed to complain about it.


E-mails mean jack and shit. Is the disruption happening ON SITE? No. The whiner e-mailing behind people's backs like this is Elementary School should be summarily ignored. It's a fucking HANDLE for crying out loud. Anyone letting a fictitious handle bother them doesn't belong on the internet, PERIOD. And you should be doubly-so kicked off moderation staff for pandering to such absolute childish nonsense.


I think you're mistaken about the emails. If one HN user gets enough activation energy to email us, the odds are that they represent a whole group of users who are having the same experience, most of whom won't email. So it pays to take a single email seriously. Of course sometimes the emails are more...eccentric, but those are different cases.

I'm not going to count the rest of this post as a guidelines violation because I understand how things like this can drive a person up a wall and we all go on tilt sometimes. But I do want to ask you to make sure not to post like https://news.ycombinator.com/item?id=22082038 and https://news.ycombinator.com/item?id=22068236. Those are the kind of thing we ban accounts for, and I don't want to have to ban you again. Most of your recent comments have been fine for HN.


"But I do want to ask you to make sure not to post like https://news.ycombinator.com/item?id=22082038"

Oh, I can't tell the truth about what's happening in my state due to OTHER states? Gracias. I didn't even call anyone names. I stated a plain fact and you let butt-hurt people called out on their BS have the advantage.

You are beyond disappointing as a moderator.


Shopify’s REST API returns 402s when the shop whose data you’re interacting with hasn’t paid its Shopify bill. Always thought it was an interesting usage cause the payment-required relationship is between the shop and Shopify, as opposed to the shop and the application hitting the API.


Actually I'm not sure that is interesting - from Shopify's perspective it is payment-required. If the shop's dodgy JS sent a malformed request body, you'd get a 400 - even though the bad-request relationship is between the shop and Shopify.


It does violate the contract of 4xx errors though, that a 4xx indicates a client error. If the store hasn't paid up, that's not the clients fault nor can they fix it. It should be some kind of 5xx for customers.


If an admin disables your account by accident, that's still a 401. Just because the client can't change something, doesn't mean it doesn't fit along with the 4XX brand.


401 means authentication is required. If Shopify is sending that to clients, because admin disabled access, that's just another example of abusing the error codes


Yeah ... current practice treats the need for payment as a permissions issue and thus 403.

But in Shopify’s case, the client has no permissions problem.

What you’re describing really is a 500-range issue ... or even an old fashioned 404.

Like I said on another comment, this really is a header or body issue.


Yeah I am thinking 503 to be the most appropriate.


At Reddit if there was a bot that was hammering us too hard, I’d reconfigure the load balancer to return a 402.

Sometimes the bot would stop after the first request. I’d always wondered if it was because it stopped after a 4xx response or if I was crashing the bot.


Didn’t Tim Berners-Lee originally envision a way to pay for individual World Wide Web content via micro-payments? This would have been perfect for that. While most content today is monetized via advertisements (which ultimately directs which content gets published to maximize views), I’m guessing this was originally meant to enable the sort of transactional content delivery originally envisioned at the onset the web.

I know there have been multiple experiments with content micropayments (I remember google had a product that was meant to allow you to charge up a wallet and use it to avoid displaying ads on participating news publications), and I vaguely remember reading something about Brave doing something similar. Really curious if this would go anywhere in this context.


I think this idea is really only viable now that we have cryptocurrencies--just to keep your payment information out of the wrong hands. That said, the popularity of adblockers has forced website owners to rely more on affiliate links and sponsorships instead of ads in the traditional sense.


I think websites are still using ads.

The problem with micropayments is that people get sticker shock. You put $10 in your micropayment account, browse around, and that money is gone whereas your friends that just look at ads and ignore them still have $10. (This was my impression, anyway, from when Google was testing that "pay to disable ads" service.) This means that publishers are forced to lower the price of an impression, and of course then advertisers ask to pay less. Guess who loses out? Publishers and the ad networks. Guess who would be well-placed to encourage the adoption of micropayments? Publishers and the ad networks. That's why we don't have micropayments. Getting money from consumers is an exercise in frustration and a race to the bottom. Getting money from businesses is an exercise in "add an extra 0 to the price and see if they still buy".

Having said that, micropayments seem to be working fine on platforms like Twitch.


I’m going to break character and talk about my work - I’m at a company, Scroll.com , that sorta does micropayments - but instead of having an account that you drain as you browse, we have a flat monthly subscription that we divide up among the sites in our network. Payout is based on the ratios of how much time you spent on each site. So if you read a lot or a little it’s the same, from your point of view. And generally it still delivers more $ per impression than advertising would.

Also, we hope that it will incentivize better content than impression-based payments does


Isn't that what flattr did?


there are a few competitors in this space, yes. We also get compared to Brave’s attention coin system. We’re differentiated in that we parter with major news-media sites - newspapers and magazines, mostly, so far.


I recall having a similar idea a few years back. How do you signup clients who insist on a larger payout? Do you have any policies in place to dissuade content producers from displaying ads to your users?


We _require_ that ads and other trackers are removed for our customers (basically, when we have a certain cookie set). And our users know that if they see our logobar on a site that they shouldn’t see ads- so they report if something goes wrong.

But cash-wise - the pitch is only that our users will bring in more money than ads - if you want to, for example, put premium content behind a paywall, that’s fine, we don’t get involved with that. But, like with advertising, the only real way to increase your payout is to get more unique users.


I have had this idea also in my head for quite a while. Did not bother to search if it was already done. I am do tired of paywalled things/ads. I do not lind paying, but I don't want to subscribe everytime someone sends me a paywalled link on another website. How many websites and customers do you have?


here’s the official list of sites: https://scroll.com/sites and we’ll be adding more soon

I’m not sure that our user count is public information right now - but we just came out of private beta last week and it’s growing fast!


Sigh. Crypto"currencies" are a scam. Earlier: https://news.ycombinator.com/item?id=21145147 https://news.ycombinator.com/item?id=21077708

Edit: downvotes are funny when I link a 70 upvoted post...


I downvoted you because neither of your links clarified why cryptocurrencies wouldn't satisfy a micropayment niche for 402 negotiation, other than "they're a Ponzi scheme." If you'd discussed Brave BAT, or the latency issues involved with posting a transaction or the dust issues with small payments, it would have been on-topic.


They are specifically NOT a Ponzi scheme, they are a new kind of scam.

And isn't it obvious it can't satisfy a micropayment niche because ... it's a scam? Any moment the value of it can drop to zero, someone might walk away with the contents of your wallet -- and that someone might be your exchange. All of these had examples.


> Any moment the value of it can drop to zero

As opposed to... what?

> someone might walk away with the contents of your wallet

Completely depends on how much you care about securing your wallet. I wouldn't say this is a common occurrence at all.

> and that someone might be your exchange.

An exchange is where you go to trade currencies, why are you keeping your money there? And how is that a problem of the currency?


Yes, although there exist no libraries which let one easily implement such services. Simple on-chain transactions also require a transaction fee every time a micropayment is made, and due to this and the fact that blockchains still not scale to more than a few tx/s, the usage of payment channels is required.

Here's a project of mine from a while ago: https://github.com/void4/paymentchannel


You don't need crypto-currencies for something like this - just a payment broker, like PayPal.


New ultra-low-cost transfer networks like Bitcoin’s lightning seem necessary and sufficient to enable something like this. I would be happy to set a budget of e.g. a few cents a YouTube-minute that got paid out automatically by my browser.


The problem isn't the tech; one could build a centralized micropayment system long before lightning was viable.

The issue is that receiving and sending bitcoin payments makes you regulated like a wire transfer service, and the resulting license costs to operate such a business are approximately 1MM USD per US state in which you wish to operate (before you can send a single payment).

It's madness. All of the cool micropayment businesses I want to start are illegal now.


But do you need to receive and send them at all? Couldn't you just act as a coordinator, sending the site's BTC address to the client so that they can pay them directly?


I don't understand. If I accept bitcoin payments, does this make me a wire transfer service?

If it makes the payment service provider a wire transfer service then Bitcoin and BTCPayServer already solves this.


I think it’s accepting bitcoins on behalf of another party that makes you a wire transfer service.


I think this actually amounts to a mistake in the protocol design: It should not be a 4xx status code at all.

From the current list of status codes[0]:

    3xx: Redirection - Further action must be taken in order to complete the request
    4xx: Client Error - The request contains bad syntax or cannot be fulfilled
"402 Payment required" is not a client error (though it is possibly a reflection of client state). The appropriate status indication should be a 3xx status, say "306 Payment required".

Bad design choice as it currently stands.

[0] https://www.iana.org/assignments/http-status-codes/http-stat...


4xx is more broadly "this request cannot be fulfilled, but it's the client's fault/remit/configuration, not the server's".


401 and 403 are authentication related, so it fits in well.


You're absolutely right. So by the same logic I'll argue that those should also be 3xx codes and not 4xx. After all, being "unauthorized"/"forbidden" is a valid state for a client to be in (so not an error!) albeit one that might not be fixable by the client, whereas "payment required" seems to imply that the client can fix the condition.


401 is used for logins in the proper case. In practice 403 is used here too. The example of HTTP authentication requires a follow up request to be made. This would be unresolvable if the user doesn't have an account or couldn't sign up.

403 would be used anytime the user doesn't have permission. This could be an authenticated user who simply does not have permission to access the requested resource.

Unlike 3xx these states require user intervention. If you trust your browser to save passwords, perhaps not. Similarly for a 402, a payment flow would be required before the request could be completed.

Again, you might choose to trust a resource that prompts you with a 402, but that would be like automatically sending your password.

Usually when building a webapp, your 401 error page will contain a login/signup form, or you can use the HTTP authentication scheme. There's no need to redirect, because your 401 contains the information needed for the user.

3xx on the other hand is usually handled by the client, but I may be mistaken. Take care.


It seems like a proper status code if client visits an url behind a paywall. Very similar to 401. 401 also shows client state of not being logged in.

This error is fixable by client who has to pay.


I would say this is too high level for the HTTP protocol. It sounds like an application-level check. If we had application-level error codes bubble up to the HTTP layer like this, we would have trouble keeping up with them all.


I'm on the fence about whether this is pedantic, but in the OSI model, this absolutely is the application level.


I was not strictly referencing the OSI model here, despite using terminology that conflates it. In my comment, I am using "application" to refer to the thing that the HTTP protocol is transporting. Example: Making a payment with the PayPal API. PayPal is the application, interfaced with HTTP. If I want to return an error code that an account was banned, I am arguing we should not be returning esoteric HTTP error codes but stick to basic ones and send the PayPal-specific error codes as payload.

Here's a real-world example with Linux.

  eclipse ~ # route add 29834
  SIOCADDRT: No such device
"No such device" is -ENODEV. Here's a list of all of them: https://www-numi.fnal.gov/offline_software/srt_public_contex...

In the above example, the developer is trying to retrofit one of Linux's standard error messages to one that best fits the condition this application has encountered. Do you think that error message makes any sense to the user? I don't.

Let's try another one:

  eclipse ~ # route del 1234
  SIOCDELRT: No such process
Choosing to use Linux's errno.h here instead of a custom message is kind of like choosing to use using HTTP's status codes to get your application's problem explained to the user, even though there might not be an HTTP-level code that specifically fits the problem description. Maybe 402 Payment Required works for payments, but what about something else? What if you need to first do action x before doing action y, should we have HTTP error 469 DoXBeforeY? That's what I was trying to explain.

Wikipedia's page on the OSI model references this as "application-entity" and "application":

When identifying communication partners, the application layer determines the identity and availability of communication partners for an application with data to transmit. The most important distinction in the application layer is the distinction between the application-entity and the application. For example, a reservation website might have two application-entities: one using HTTP to communicate with its users, and one for a remote database protocol to record reservations. Neither of these protocols have anything to do with reservations. That logic is in the application itself. The application layer has no means to determine the availability of resources in the network. [0]

[0] https://en.wikipedia.org/wiki/OSI_model#Layer_7:_Application...


Maybe a casual user doesn't care, but a power user / dev trying to script it would benefit. Just like how some users of Linux applications just use them interactively and read the English language stderr stream, while others appreciate a myriad of exit codes so a calling script can unambiguously do different things depending on what sort of problem the application is presenting.


Well, the exit codes of both of those commands (despite being different) is actually 7. But 7 does not match either error string, so the power user would have to string search it anyway.

  eclipse ~ # route add 1234
  SIOCADDRT: No such device
  eclipse ~ # echo $?
  7

  eclipse ~ # route del 1234
  SIOCDELRT: No such process
  eclipse ~ # echo $?
  7
Maybe I used a bad example? I get your point though.


This seems more something that should be in the headers.

Application level data bubbling up to headers is already a major problem. I don’t think one more will hurt.


HTTP is an application level protocol.


It is on the OSI model, but it is not the context I am talking about. Think about an application you build. You just happen to interface over it with HTTP, but you don't have to. You could interface with it using FTP or some other protocol. The suggestion I am making is we shouldn't use esoteric protocol-level error messages but stick to basic ones and instead pass any specific status codes as payload data.



Nowadays most news websites send this as a "200".


200, including partial content, and still with adds.


200 with full content for robots


The RFC offers no reasoning for this besides

> The 402 (Payment Required) status code is reserved for future use.

Isn't this obviously domain-specific and something that should not be part of the transfer protocol?


Well an older draft version of spec says:

>"The parameter to this message gives a specification of charging schemes acceptable. The client may retry the request with a suitable ChargeTo header."

https://www.w3.org/Protocols/HTTP/HTRESP.html

And charge-to is defined as

>"ChargeTo:

>This line if present contains account information for the costs of the application of the method requested. The format is TBS. The format of this field must be in extensible form. The first word starts with a specification of the namespace in which the account is . (This is similar to extensible URL definition.) No namespaces are currently defined. Namespaces will be registered with the registration authority .

>The format of the rest of the line is a function of the charging system, but it is recommended that this include a maximum cost whose payment is authorized by the client for this transaction, and a cost unit."

https://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#z10


> The new W3C Payment Request API [4] makes it easy for browsers to offer a standard (and probably(?) already accessible) interface for the payment data entry screen, at least. https://www.w3.org/TR/payment-request/


The Payment Request API doesn't use 402 Payment Required, does it?


It really could


> transfer protocol

Not to be "that guy" but HTTP is an application protocol, not a transfer protocol -- this kind of thing definitely wouldn't be appropriate for TCP but it sort of makes sense for the original vision of the web.


HTTP is a transfer protocol. That’s what the second T stands for. It is also an application protocol. There is no “transfer” layer in the OSI model.


Interesting, I have only heard someone refer to "transfer protocols" as a synonym for "transport protocol". Regardless I think the point stands -- HTTP does much more than transfer, and has an opinionated model on how to deal with web resources.


In this case "reserved for future use" means "don't use this for new proposals, because we already assigned it to something else that didn't pan out."


Packix.com uses this for paid iOS jailbreak tweaks/themes! This is what I get if I try to install a tweak that I haven't paid for: https://i.imgur.com/RpomgNa.jpg


Would be nice if all those news sites with "you've read n articles, subscribe to read more" popups could return 402. Then I could have my browser automatically disable js for them and reload.


Problem is, things like this will never be used. Everybody wants to have their own application chrome, so these sort of features end up buried and forgotten.


Every page having its own payment system is a bug, not a feature. It relies on every vendor to independently implement secure payments and it trains users to type their credit card number into any old web site.


What’s the one payment system we should use for all payments in any country for every website?


This is a plausible use case for Bitcoin (over the Lightning network). Works in any country, and could be used by any website.


The only people really promoting Lightning are those who haven't used it.


We built the Condé Nast paywalls (New Yorker/Wired/Vanity Fair) using the 402 status code. A 402 indicates to the browser that no acceptable payment method was negotiated and the content returned is not the full url requested.

We imagine clients sending an "Accept-Payment" header just as they send an "Accept" or "Accept-Language" header today. When the server is unable to satisfy their request, it returns a 402 indicating that no acceptable payment method was found.

It's true that browsers may not be currently sending these Accept-Payment headers; we auto-create the headers at the edge based on other headers (cookies). Conceptually this simplifies our stack and gives us a way that we might be able to have more of a "conversation" between web users and the site about how they want to monetize our content.

For instance a user may have ad-block enabled so why not tell the server that ("Accept-Payment: ads;q=0") and we'll serve the page based on this information.

I envision a future where the web browser may have multiple payment methods built into it (micro-payments, subscriptions, ads, etc.) and a "conversation" happens between the client and server to figure out what the "best" way forward is for both parties. We don't need new headers or methods for this, we simply need to re-use existing status codes and headers.


The full page distinction is very useful and nuanced. You're returning partial content, so it's not a regular 4xx, but readers can't go past the fold, so it's not a 2xx. It's a good niche for the status code. I hope these headers catch on.. payment vs. content negotiation seems a natural fit.


The difficulty of micropayments in my experience is 1) payment processing and 2) taxes. Our payment systems and laws just aren't set up to make this feasible. I think it would actually be common and well-accepted if these obstacles magically we're removed.


Nanocurrency addresses the payment processing end. Instant, feeless and decentralized transactions.

https://nano.org https://nanolinks.info/#games


The difficulty in this case is that the user must use this service. Most users want to use credit card or PayPal.


I wish I and other colleagues had shirts showing this error back then, when working at a place without seeing a dime for the first 3 months.


Lightning Network will make use of this code during this decade


Brave browser should implement this. Or metamask


Here's the GitHub issue with the discussion for Joule (similar to Metamask but for Bitcoin's Lightning Network): https://github.com/joule-labs/joule-extension/issues/46


Just changed all my 404 error pages to 402


402 makes sense. "Theres no page here but I can make a page here if you pay me."


I use this status code in my Go middleware for true pay-per-call APIs (payable via Bitcoin's Lightning Network) and my demo deployment:

- https://github.com/philippgille/ln-paywall

- https://lightning.ws


It is easier for the frontend developer to look only to the status code of the response and pop up a paywall or something, rather than some message in the boby. The same goes for 401 Unauthorized or 403 Forbidden, etc.


Late stage corporativism...


402 is the area code in Eastern Nebraska (think Omaha and Lincoln)


This is the moral equivalent of a white flag in the sense that were surrending the idea of free global internet. We shouldn't own the air bro. (You know after we've managed to snip in half all the wires).


You already pay to use the internet. You just do it in underhanded inefficient ways like giving advertising companies access to your brain.


In 2011 I launched my bootstrapped startup "LinkPeek" (https://linkpeek.com) and I used the error code 402 when a customer's account was delinquent.

HTTPPaymentRequired

https://docs.pylonsproject.org/projects/pyramid/en/latest/ap...

LinkPeek is a Pyramid application. I'm streaming live tonight as I read hacker news. Join me here https://www.twitch.tv/fxhp


That is strangely interesting.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: