HTTP 402 Payment Required
This page describes an extension to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP Protocol]. The protocol defines various error responses such as 404 Not Found and 401 Unauthorized. It defines 402 as Payment Required, with a statement that the code is reserved for future use. This page describes an extension to HTTP to specify the 402 response. The response means that the web browser must pay the web server to gain access to the document. This page describes how the server and browser negotiate and perform the payment. The negotiation occurs over HTTP but the actual payment goes through the payment system described in LeonhardIntro.
This page will eventually be turned into a RequestForComments and submitted to IETF as an Internet Draft.
New HTTP Headers
The server advertises its accepted methods of payment with this HTTP header field:
⇦ HTTP402-AcceptedMethods: IPP-PYR, IPP-PYE
Future methods may include Paypal, eGold, or digital-coin based schemes.
When the payer and payee use different currencies, there will be an exchange rate in addition to the transaction fees. Both the exchange rate and fees determine the amount debited from the user's account. In some cases it is difficult to determine what are the fees and what is the exchange rate. It is even more difficult to force a bank to properly determine and report this information. Thus, we choose to leave fee information out of the protocol. The protocol will specify debit amounts and deposit amounts, in their respective currencies.
If a client wishes to display a 'fees' value to the user, it may determine a suitable exchange rate and perform its own calculation of the transaction fees.
PayeeHandled Method (IPP-PYE)
If a server includes IPP-PYE in the HTTP402-Accepted header, it must also include an IPP-PYE-DepositAmount header. This is the demanded deposit amount.
⇦ IPP-PYE-DepositAmount: USD 0.12
If the client chooses IPP-PYE, it reissues its initial HTTP request, including the IPP-PYE-DepositAmount header, and adding the IPP-PYE-DebitBank header.
⇨ IPP-PYE-DepositAmount: USD 0.12
⇨ IPP-PYE-DebitBank: 711.com
The server then contacts its banks and chooses an deposit account. A good server will choose the account and route that has the lowest debit-amount. This saves the customer money. A bad server could route the transaction through its own intermediary, charging high fees. After the server chooses a deposit account, it sends the transaction info to the client. The headers now contain all of the transaction information, except for the user's debit code.
⇦ IPP-PYE-DepositBank: mbank.com
⇦ IPP-PYE-DepositCode: 597364219
⇦ IPP-PYE-DepositAmount: USD 0.12
- ⇦ IPP-PYE-Debit`Bank: 711.com
⇦ IPP-PYE-DebitAmount: CDN 0.73
Now the client may prompt the user to accept or deny the transaction. The client can try to calculate a transaction fee and present that to the user along with the cost and total. If the debit and deposit accounts are in different currencies, the client can use current market exchange rates to estimate the price and fee in the debit currency. A simple client will just present the debit-amount.
It is my hope that competition will drive merchants to offer “NO FEE” service. Merchants would then seek to minimize fees, making the system more efficient.
If the user denies the transaction, the client may simply forget about the whole thing. It need not close the connection to the server. Perhaps the server should specify an expiration time for the pending transaction?
If the user accepts the transaction, the client will obtain a debit code. This may be a pre-issued debit code stored in the client. Or the client may contact the debit bank and buy a new debit code with a fixed value, equal to IPP-PYE-DebitAmount. Or the client may buy a debit code that is locked to the details of the pending transaction: deposit bank, deposit code, and debit amount. The debit code is the final piece of the puzzle. After obtaining it, the client reissues the HTTP request with the full set of transaction headers:
⇨ IPP-PYE-DepositBank: mbank.com
⇨ IPP-PYE-DepositCode: 597364219
⇨ IPP-PYE-DepositAmount: USD 0.12
⇨ IPP-PYE-DebitBank: 711.com
⇨ IPP-PYE-DebitCode: 127292993
⇨ IPP-PYE-DebitAmount: CDN 0.21
These headers represent an authorization to perform the transaction. They also provide all the necessary information to do it. The server receives the information and performs the transaction via its bank. If it the transaction succeeds, it caches that result and grants the client access to the website content. If the transaction fails, it responds with the IPP-PYE-Failure header and IPP-PYE-DepositAmount to restart the transaction.
- ⇨ IPP-PYE-Failure: 123 Invalid debit code.
⇨ IPP-PYE-DepositAmount: USD 0.12
TODO:
- Determine the format and error codes for the failure headers.
If the client doesn't receive an IPP-PYE-Failure header, it assumes that the transaction succeeded. It sends the header fields with every subsequent HTTP request to the server. This is similar to HTTP AUTH, which sends the username and password with every HTTP request. The client can remember the transaction across sessions, if configured to do so by the user. The server may also store the information into a browser cookie to facilitate multi-session payments.
- Note:
I think that the IPP-PYE-Deposit* fields should be optional if the debit code is not locked to that information. This gives the server the opportunity to choose a different account. This raises the question of whether or not the fields in the HTTP402 transaction represent a legal negotiation. Obviously the server should never perform a transaction that results in a DebitAmount higher than what it previously indicated. There are some situations where a lower DebitAmount might also be detrimental to a client. So perhaps all fields should be mandatory and represent a contract?
PayerHandled Method (IPP-PYR)
This method shifts the workload to the client, but protects the client from some collusion between the server and intermediaries. The client can choose the transaction’s path or trust its bank to make the most economical choice. The client makes the deposit and sends a ‘receipt’ to the server. The server verifies the transaction and then provides access to content.
Initially, the server provides the client with its account info and the required deposit amount. This is given in the initial HTTP 402 response:
⇦ IPP-PYR-DepositBank: mbank.com
⇦ IPP-PYR-DepositCode: 597364219
⇦ IPP-PYR-DepositAmount: USD 0.12
The client may be configured with multiple accounts. The client queries each bank to find out the DebitAmount for each account. This is the amount of money that would be withdrawn from the account if that account was used in the transaction. The client then presents the accounts and debit amounts to the user. The user chooses one. The client then performs the transaction using that account and replies to the server:
⇨ IPP-PYR-DepositBank: mbank.com
⇨ IPP-PYR-DepositCode: 597364219
⇨ IPP-PYR-DepositAmount: USD 0.12
⇨ IPP-PYR-DebitBank: 711.com
⇨ IPP-PYR-DebitCode: 127292993
The server queries its bank to see if the deposit occurred as indicated. If it did, it caches that information and grants the client access.
The client sends those header fields with every subsequent HTTP request to the server, just as with HTTP AUTH. The client can remember the payment across sessions, if configured to do so by the user. The server may also store the information into a browser cookie to facilitate multi-session payments.
- Notes:
What happens if the server provides different values for IPP-PYE-DepositAmount and IPP-PYR-DepositAmount? I suppose any server could charge differently. Even if the fields were combined into one, say IPP-DepositAmount, the server could still manipulate the transaction by collecting fees via its own intermediary. It may be harder to use one’s own intermediary than to just let one’s bank choose the route. So merging the two fields into one may produce a barrier to servers charging different amounts depending on the transaction type. Is this a good thing?
Should the protocol include a dummy field of random length to frustrate analysis of SSL message length? The presence or absence of the IPP-PYE-DebitAmount field in the client’s HTTP requests indicates that the transaction was Payee Handled (PYE). Also, the length of the bank’s name and debit code could be useful to an attacker. I suggest a field called IPP-Dummy: FFFF, where FFFF is replaced by a random string of characters of length 1-255. It is important that a new string be used for every message.
[http://floopityjoop.com/Name Analysis.html Name Analysis]
