This document outlines how to register payment applications, create payment requests, and reply with payment responses using a standard HTTP API.

The most effective way to report issues and request features is to engage the working group via the Github issue tracker for the Working Group. Submitting issues as well as pull requests for changes to the specification are encouraged.

Introduction

This HTTP API enables a web application to initiate payment for a product or service by responding with an HTTP 402 Payment Required response and enough data to initiate and complete a payment flow. The implementation of this feature is expected to be implemented by any HTTP server and client that is interested in executing payments.

How to Read this Document

This document is a detailed specification for a HyperText Transfer Protocol application programming interface (HTTP API) for executing payments via an HTTP client and server. The document is primarily intended for the following audiences:

There are a number of Web Payments messages that are referenced and used in examples in this specification. The normative definition of these messages, as well as how to express them in a variety of syntaxes, is specified in [[!WEBPAYMENTS-HTTP-MESSAGES]].

Terminology

The current terminology that is pulled into the HTTP API specification needs some simplification and alignment.

Payment Flow Overview

The diagram below outlines a basic HTTP client payment flow with no errors. The basic flow starts out with the payer optionally accessing a protected resource and being notified that payment is required. The payee provides a URL where a payment request for the resource can be fetched. The payer fetches the payment request, selects a payment app, and sends the request on to the appropriate payment app for processing. The payment app initiates the payment and sends a payment response back to the payer. The payer then forwards the payment response back to the payee. If there are no errors, the payee then grants access to the resource that was purchased.

Generalized payment flow
The generalized payment flow that the HTTP API enables.

Detailed Payment Flow

It may be a good idea to return the payment request with the 402 response. The concern is that this would be a misrepresentation of the resource. The counter-argument is that a client shouldn't interpret a 402 response as the resource, and since 402 has not been formally defined yet, we could define it to always come with a payment request response.

  1. The payer requests access to a resource via an HTTP request.
  2. The payee's web page requests payment by responding with a 402 Payment Required response code and a URL encoded in the Location header to fetch the request from.
  3. The payment mediator fetches the request from the URL specified in the Location header in the previous step.
  4. The payment mediator scans the list of previously registered payment apps and finds matches against paymentTerms in the payment request.
  5. A payment app is selected by the payment mediator or the payer. The process MAY consist of one or more of the following steps:
    This payment app selection process should probably be moved out into a separate payment mediator specification and referenced from this specification.
    1. If there is only one app that matches, that is automatically set to the selected payment app.
    2. If there is a pre-existing preference set by the payer that narrows the selection of the payment app to one match, the match is set to the selected payment app.
    3. If there is more than one potential match, the payer is asked which app they would like to use and the selection is set to the selected payment app
    4. If there are no matches, the payer is notified and may be taken to an alternate flow where a matching payment app is acquired.
  6. The payment request is forwarded to the selected payment app.
  7. The payment app handles the payment request and returns a payment response. This could happen in a number of ways depending on the payment method:
    The steps below are intended to provide for various flows envisioned by the Web Payments ecosystem. This algorithm is merely a starting point, is very much a work in progress, and is not asserted to be correct at present:
    1. Let "selectedApp" be the payment app selected by the payment mediator.
    2. Let "selectedMethod" be the payment method provided by the payee and selected by the payer.
    3. If selectedMethod.paymentRequestService exists, re-direct the user there (payee-based PSP).
    4. If selectedApp.paymentRequestService exists, re-direct the user there (payer-based PSP).
    5. Otherwise, the payment response can be generated locally (local PSP - Bitcoin and others).
    1. If the payment app does not require the payment flow to switch to a 3rd party payment processor (e.g., cryptocurrency or stored credentials), then the payment response is generated locally.
    2. If the app does require the payment flow to switch to a 3rd party payer payment processor (e.g., push-payment like a PayPal/Google Wallet-like app, ACH, ISO20022 style app):
      1. The payment app communicates with the 3rd party payment processor who processes the payment and returns payment method specific response data which is used by the app to generate a response.
    3. Once the payment app finalizes the data required in the payment response, even if the message is to acknowledge that the payment failed, the payment response is generated and the payer's payment mediator is notified via an HTTP 200 success code.
      Returning an HTTP status code of 200 when a payment fails is controversial. The current thinking seems to be that 200 is the right thing to do as the message was processed successfully (that's what the 200 is referring to). The result of processing the message, however, has nuance that may be dependent on the payment method used. As a thought experiment, what should the HTTP response code be in the following cases:
      1. Funds transfer was initiated and completed. Clearly 200, right?
      2. Funds transfer was initiated, but network delay may cause it to fail at a later point in time (ACH, etc.). 102 or 202?
      3. Request for subscription was noted and is setup, but no funds were moved. 200?
      4. Payment submitted to network, but network didn't respond with an auth code. 504?
      5. Cryptocurrency payment was submitted to network but a fork has been detected and it is unclear if we're on the winning or losing fork. 102 or 202?
      There are not enough HTTP status codes to try and enumerate the nuanced potential outcomes so the best we can do at present (it seems) is to just report on whether or not the payment request was processed successfully or not and let the payee determine if the outcome of the transaction was valid from their viewpoint. In many nuanced cases, it's up to the payer to decide if it was "successful" or not (like waiting on a certain number of acknowledgments from a blockchain, for example).

      Melvin Carvalho has also raised an issue noting that we may not want to use 402 and the Location header, but rather an additional HTTP header called Payment that is compatible with multiple 4xx error conditions.

  8. The payment response is forwarded to the payee at the URL provided in the payment request.
  9. The payee MAY contact the payment network to either:
    1. request that a payment is processed using the credentials provided in the payment response.
    2. verify that the proof of payment provided in the payment response is valid.
  10. The payment network responds to the payment instruction/verification request.
  11. The payee notifies the payer that the purchase was successful.
  12. The payer attempts to access the protected resource again.
  13. The payee returns the resource to the payee (as the payee has now paid for it).

Web Payment Operations

It is quite likely that most deployment will incorporate the mediator and app in the same system and (to facilitate autonomous payments) will only have a single built-in payment app therefor the document should make it clear that registration is not a prerequisite for payment and in most cases will not be required.

Payment app Registration

  1. The payer's HTTP client navigates to a payment service provider website and authenticates itself to fetch a payment app to register:
    GET /apps/visa HTTP/1.1
    Host: mybank.example.org
    Date: Tue, 07 Jun 2017 20:51:35 GMT
    Accept: application/json
    Authorization: Digest username="jdoe", realm="jane@mybank.example.org", ...
            
    While digest authentication is used above, more advanced authentication schemes may also be employed. For example, the mechanism below uses HTTP Signatures and public/private key cryptography to authenticate the client with the server:
    GET /apps/visa HTTP/1.1
    Host: mybank.example.org
    Date: Tue, 07 Jun 2017 20:51:35 GMT
    Accept: application/json
    Authorization: Signature keyId="https://mybank.example.org/people/jane/keys/42",
       algorithm="rsa-sha256",headers="(request-target) host date",
       signature="jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7qnVrGR+30bmB
                  gtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0jOyn9sXOtcN7
                  uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w="
            
  2. The payment service provider MUST respond with the payment app or an HTTP error code. If successful, something like the following will be returned:
    HTTP/1.1 200 OK
    Date: Tue, 07 Jun 2017 20:51:36 GMT
    Content-Type: application/json
    Content-Length: 412
    
    {
      "type": "PaymentApp",
      "paymentMethod": "https://payments.example.org/payment-schemes#Visa",
      "label": "ExampleBank Visa Card",
      "paymentRequestService": "https://mybank.example.org/services/cards/2745023475"
    }
            

Initiating a Payment Request

  1. The payer's HTTP client accesses a resource that requires payment:
    GET /movies/dr-strangelove HTTP/1.1
    Host: videos.example.com
    Date: Tue, 07 Jun 2017 21:31:35 GMT
            
  2. The payee's HTTP server responds with a 402 Payment Required response and the URL where the payment request may be fetched via the Location header:
    HTTP/1.1 402 Payment Required
    Date: Tue, 07 Jun 2017 21:31:36 GMT
    Location: https://videos.example.com/payment-requests/dr-strangelove
            
    It's currently not clear if having an extra round-trip (steps 2 and 3) is beneficial. The alternative is to respond with an HTTP 402 and the payment request (step 4) when the GET for the initial resource is performed. This removes the need to do an extra GET at the expense of providing a little more flexibility wrt. the location of the payment request service. For example, having the Location header enables software developers to split media servers from payment processing servers. That said, there are techniques to do this today without the extra layer of indirection.
    The model described here does not yet take into account "push" payments. While there is nothing in this design that precludes payments pushed from a payer to a payee, explicit support and an example that illustrates this need to be included in the document.
  3. The payer's HTTP client accesses the payment request resource:
    GET /payment-requests/dr-strangelove HTTP/1.1
    Host: videos.example.com
    Date: Tue, 07 Jun 2017 21:31:37 GMT
            
  4. The payee server provides the payment request.
    HTTP/1.1 200 OK
    Date: Tue, 07 Jun 2017 21:31:38 GMT
    Content-Type: application/json
    Content-Length: 873
    
    {
      "type": "PaymentRequest",
      "description": "Payment for Dr. Strangelove",
      "paymentTerms": [{
        "paymentMethod": "https://payments.example.org/payment-schemes#Visa",
        "paymentAmount": {
          "amount": "2.99",
          "currency": "USD"
        }
      }],
      "paymentCompleteService": "https://videos.example.com/services/paymentComplete?transaction=923847298"
    }
            

Generating a Payment Response

  1. A payment app is selected by the payment mediator to process the payment request generated in the previous section.
  2. The paymentRequestService URL, provided in the payment app or the payment request, is used as the HTTP POST endpoint. The payment service provider that is providing the payment app interface receives the payment request, authenticates the payer, and proceeds with the payment:
    POST /services/cards/2745023475 HTTP/1.1
    Host: mybank.example.org
    Date: Tue, 07 Jun 2017 20:51:35 GMT
    Accept: application/json
    
    {
      "type": "PaymentRequest",
      "description": "Payment for Dr. Strangelove",
      "paymentTerms": [{
        "paymentMethod": "https://payments.example.org/payment-schemes#Visa",
        "paymentAmount": {
          "amount": "2.99",
          "currency": "USD"
        }
      },
      "paymentCompleteService": "https://videos.example.com/services/paymentComplete?transaction=923847298"
    }
            
  3. The payment app generates a payment response message that contains enough information to verify that the transaction has completed in success or failure:
    HTTP/1.1 200 OK
    Date: Tue, 07 Jun 2017 20:51:36 GMT
    Content-Type: application/json
    Content-Length: 623
    
    {
      "type": "PaymentResponse",
      "description": "Payment for Dr. Strangelove",
      "paymentMethod": "https://payments.example.org/payment-schemes#Visa",
      "details" : {
        "cardholderName": "John Smith",
        "cardNumber": "123456789012345",
        "expiryMonth": "12",
        "expiryYear": "2020",
        "cardSecurityCode": "000",
      }
    }
            
  4. The payment response is then relayed back to the payee by the payment mediator using the paymentCompleteService URL provided in the initial payment request:
    POST /services/paymentComplete?transaction=923847298 HTTP/1.1
    Host: videos.example.com
    Date: Tue, 07 Jun 2017 20:51:35 GMT
    Content-Type: application/json
    
    {
      "type": "PaymentResponse",
      "description": "Payment for Dr. Strangelove",
      "paymentMethod": "https://payments.example.org/payment-schemes#Visa",
      "details" : {
        "cardholderName": "John Smith",
        "cardNumber": "123456789012345",
        "expiryMonth": "12",
        "expiryYear": "2020",
        "cardSecurityCode": "000",
      }
    }
            
  5. The payee validates the payment response, (if necessary it processes the payment) then sets the appropriate access control for the resource, and re-directs the payer to the resource:
    HTTP/1.1 302 Found
    Date: Tue, 07 Jun 2017 20:51:36 GMT
    Cookie: movieToken=2983fhfa92h3iuhf908723nkjcsdh923; Expires=Tue, 08 Jun 2017 20:51:40 GMT
    Location: /movies/dr-strangelove
            

Security and Privacy Considerations

The Working Group is currently in the early stages of the analysis of the security and privacy implications of this specification. The ongoing analysis can be accessed via the Web Payments Working Group Security and Privacy Considerations wiki .

Acknowledgements

The editor would like to thank members of the Web Payments Community Group, Web Payments Interest Group, and Web Payments Working Group for the ideas and discussion that culminated in this specification. In addition, thank you to the to the following individuals, in order of their first name, for their input on this specification: LIST_TBD