Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web Payments API and Wrapper

Web Payments API and Wrapper

A description of the Web Payments API and the work I have done to make it easier to use.

Danielle Brook-Roberge

October 18, 2016
Tweet

More Decks by Danielle Brook-Roberge

Other Decks in Programming

Transcript

  1. PaymentRequest » The Web Payments API that Google is developing

    with the W3C is built around an object called PaymentRequest. » The goal is to replace checkout forms with a uniform piece of browser interface that is connected to an internal store of payment information » It is intended to connect to a wide variety of payment methods including PayPal, but currently is only implemented for credit cards and Android Pay.
  2. Inputs » let request = new PaymentRequest(supportedInstruments, details, options) »

    supportedInstruments is a list of the accepted payment methods » details describes the order, including line items and shipping options » options is an object that configures which of the optional features of the payment sheet are enabled.
  3. Outputs » Billing information for the chosen payment method, including

    billing address if appropriate. This is the only piece of information we must request. » Shipping address and choice of shipping method. » Email Address » Phone Number
  4. Using the PaymentRequest Object const makePaymentRequest = () => {

    if (!('PaymentRequest' in window)) { return Promise.resolve() } return new PaymentRequest(supportedInstruments, details, options) .show() .then((result) => { console.log(result) result.complete() }) .catch((error) => console.log(error)) }
  5. Limitations of this approach » Using PaymentRequest as above is

    the simplest way to make use of Web Payments » While simple, this approach allows requests for payment details, email addresses, and phone numbers. » Shipping information generally requires a more complex approach, as the order details may need to change in response.
  6. PaymentRequest with Listeners const request = new PaymentRequest(supportedInstruments, details, options)

    request.addEventListener('shippingoptionchange', (e) => { details = newDetailsFor(details, request.shippingOption) e.updateWith(Promise.resolve(details)) }) request.addEventListener('shippingaddresschange', (e) => { details = newDetailsFor(details, request.address) e.updateWith(Promise.resolve(details)) }) request.show()// ...
  7. Benefits of Listeners » These listeners let us vary the

    shipping options and line items by shipping address, allowing applications like: » higher shipping rates for distant locations like Alaska » sales tax line items that vary by state/province » indicating that a given address is not within the vendors shipping regions » This comes at the cost of having to manage the details object manually.
  8. Why We Wrap » The low-level design of the PaymentRequest

    API requires the user to manage the details object manually, adding complexity. » The three arguments for the PaymentRequest constructor are also divided somewhat artificially, making it useful to construct a single input for the request. » The payments wrapper I have developed contains its own handlers for the payment events, and logic to update details in the most common case.
  9. Wrapper Internals export const buildRequest = (input) => { let

    state = initialState(input) const request = new PaymentRequest( produceInstruments(input), produceDetails(input, state), produceOptions(input) ) request.addEventListener('shippingoptionchange', (evt) => { state = changeShipping(state, request.shippingOption) evt.updateWith(Promise.resolve(produceDetails(input, state))) }) request.addEventListener('shippingaddresschange', (evt) => { state = changeAddress(input, state, request.shippingAddress) evt.updateWith(Promise.resolve(produceDetails(input, state))) }) return request }
  10. A React-Inspired Design » Rather than modifying the details from

    the previous conditions, we re-generate the object on every change. » The details object is then a pure function of the input object and a state object maintained in the buildRequest closure » The state is treated as immutable with any changes being applied in a copy. » This makes the code much easier to reason about, much as React does for HTML.
  11. Capabilities » The wrapper automatically maintains the order total and

    displayed line items as shipping options and tax rates change. » It allows rejection of unsupported addresses (e.g. reject all non-US addresses if the vendor only ships within the US) » It allows user-configured variations of shipping method with address. » The input is a single, simpler object that better matches the form in which we receive data.
  12. Summary » The Web Payments API is an ambitious attempt

    to revamp the web checkout process. » It is in production as of Chrome 53 but is not yet finalized » The API is modern but low-level » I have developed a high-level wrapper that reduces the need for boilerplate code in a Web Payments implementation.