Set to be announced at the upcoming Google I/O developer conference, the Payment Request API will revolutionize the way we make online payments on our mobile devices. No longer will Google Chrome users on Android have to go through lengthy checkout processes involving inputting their credit card information or logging into PayPal. Instead, the API enables website developers to send intents to supported third-party payment applications in order to make a payment. Unlike many of the other surprises that Google has in store for us, there is already a ton of public information about how exactly this new way to pay will work. We've dived into all of these documents in order to bring you some information before Google's official announcement this week.


Making Payments Easier with the Payment Request API

Let's first recap how payments are currently handled in web browsers. When you go to the checkout page of any online merchant, you are asked to input your payment information. You can either add a credit card supported by the merchant or use an integrated service such as PayPal to complete your transaction. Now, unless you've already saved your credit card information with the website (which many people are reluctant to do) or are already logged in to PayPal, it can be a hassle to get up, go to your wallet, find your card, then input the card number, expiration date, and security code. Every single time you want to make a purchase on a new website, you have to go through some variation of this process. For those of us who like to hunt for deals, this can get annoying pretty quickly.

Various online merchant checkout pages

Many credit card and banking institutions have applications available on the Google Play Store. Since we are already using these applications to monitor our financial accounts, why can't we use them to authenticate payments? That's exactly the thought process behind the Web Payments Working Group, made up of members such as Google, Mozilla, Samsung, Alibaba, Microsoft, and more. This group has been working behind-the-scenes in order to introduce a new API called the Payment Request API and a new online standard defined in the Payment Manifest Proposal in order to facilitate communication between web browsers and online merchants so the online merchant can use existing applications on an end-user's device in order to handle payments.

How it works

In order to accomplish this task, web browsers must support the Payment Request API, online merchants need to support the API by implementing what's called a Payment Method Identifier, and Android applications need to implement new services. Without going into too much detail, I will briefly explain what is happening during the checkout process.

Assuming your web browser supports the Payment Request API (more on that later), when you navigate to an online merchant's payment page you will have the option to pay with one of their supported payment handlers (credit card/PayPal/etc.) When you tap on the button to make a purchase (such as on the sample page below used by Googlers to test the Payment Request API), then the Payment Request API sends an Android intent to the supported payment application in order for that app to authenticate the user's payment.

 Let's say our hypothetical credit card application installed on a hypothetical Android device is called Bob Pay. Bob Pay will add the following to their AndroidManifest.xml file:

        <span style="font-weight: 400;"><manifest</span> <span style="font-weight: 400;">package=</span><span style="font-weight: 400;">"com.bobpay.app"</span><span style="font-weight: 400;">></span>
<span style="font-weight: 400;">  </span><span style="font-weight: 400;"><service</span> <span style="font-weight: 400;">android:name=</span><span style="font-weight: 400;">".IsReadyToPayService"</span>
<span style="font-weight: 400;">           </span><span style="font-weight: 400;">android:enabled=</span><span style="font-weight: 400;">"true"</span>
<span style="font-weight: 400;">           </span><span style="font-weight: 400;">android:exported=</span><span style="font-weight: 400;">"true"</span><span style="font-weight: 400;">></span>
<span style="font-weight: 400;">    </span><span style="font-weight: 400;"><intent-filter></span>
<span style="font-weight: 400;">      </span><span style="font-weight: 400;"><action</span> <span style="font-weight: 400;">android:name=</span><span style="font-weight: 400;">"org.chromium.intent.action.IS_READY_TO_PAY"</span> <span style="font-weight: 400;">/></span>
<span style="font-weight: 400;">    </span><span style="font-weight: 400;"></intent-filter></span>
<span style="font-weight: 400;">  </span><span style="font-weight: 400;"></service></span>
<span style="font-weight: 400;">  </span><span style="font-weight: 400;"><activity</span> <span style="font-weight: 400;">android:name=</span><span style="font-weight: 400;">".PaymentActivity"</span>
<span style="font-weight: 400;">            </span><span style="font-weight: 400;">android:exported=</span><span style="font-weight: 400;">"true"</span><span style="font-weight: 400;">></span>
<span style="font-weight: 400;">    </span><span style="font-weight: 400;"><intent-filter></span>
<span style="font-weight: 400;">      </span><span style="font-weight: 400;"><action</span> <span style="font-weight: 400;">android:name=</span><span style="font-weight: 400;">"org.chromium.intent.action.PAY"</span> <span style="font-weight: 400;">/></span>
<span style="font-weight: 400;">    </span><span style="font-weight: 400;"></intent-filter></span>
<span style="font-weight: 400;">    </span><span style="font-weight: 400;"><meta-data</span> <span style="font-weight: 400;">android:name=</span><span style="font-weight: 400;">"org.chromium.default_payment_method_name"</span>
<span style="font-weight: 400;">               </span><span style="font-weight: 400;">android:value=</span><span style="font-weight: 400;">"https://bobpay.com/put/optional/path/here"</span> <span style="font-weight: 400;">/></span>
<span style="font-weight: 400;">  </span><span style="font-weight: 400;"></activity></span>
<span style="font-weight: 400;"></manifest></span>

When an intent is sent targeting this hypothetical credit card application, then this application's service is started. All of the information necessary for our hypothetical Bob Pay app to understand what is being purchased, from which vendor, and for how much money is contained in the intent's extras:

        Bundle extras = new Bundle();
extras.putString("key", "value");
intent.putExtras(extras);

Once Bob Pay has validated the payment, then the Payment Request API receives this information in another intent sent by Bob Pay:

        Intent result = new Intent();
Bundle extras = new Bundle();
extras.putString("key", "value");
result.putExtras(extras);
setResult(RESULT_OK, result); // Change to RESULT_CANCELED on failure.
finish(); // Close the payment activity.

But how does the online merchant that supports Bob Pay know that the Bob Pay installed on your phone is the real Bob Pay, and not some malware intended to commit fraud? It accomplishes this by creating a Payment Method Manifest Identifier JSON file that is machine-readable by the browser.

        {
  <span ><span >"</span>name<span >"</span></span><span >:</span> <span ><span >"</span>BobPay - World's Greatest Payment Method<span >"</span></span>,
  <span ><span >"</span>description<span >"</span></span><span >:</span> <span ><span >"</span>This payment method changes lives<span >"</span></span>,
  <span ><span >"</span>short_name<span >"</span></span><span >:</span> <span ><span >"</span>BobPay<span >"</span></span>,
  <span ><span >"</span>icons<span >"</span></span><span >:</span> [{
    <span ><span >"</span>src<span >"</span></span><span >:</span> <span ><span >"</span>icon/lowres.webp<span >"</span></span>,
    <span ><span >"</span>sizes<span >"</span></span><span >:</span> <span ><span >"</span>64x64<span >"</span></span>,
    <span ><span >"</span>type<span >"</span></span><span >:</span> <span ><span >"</span>image/webp<span >"</span></span>
  },{
    <span ><span >"</span>src<span >"</span></span><span >:</span> <span ><span >"</span>icon/lowres.png<span >"</span></span>,
    <span ><span >"</span>sizes<span >"</span></span><span >:</span> <span ><span >"</span>64x64<span >"</span></span>
  }, {
    <span ><span >"</span>src<span >"</span></span><span >:</span> <span ><span >"</span>icon/hd_hi<span >"</span></span>,
    <span ><span >"</span>sizes<span >"</span></span><span >:</span> <span ><span >"</span>128x128<span >"</span></span>
  }],
  <span ><span >"</span>serviceworker<span >"</span></span><span >:</span> {
    <span ><span >"</span>src<span >"</span></span><span >:</span> <span ><span >"</span>payment-sw.js<span >"</span></span>,
    <span ><span >"</span>scope<span >"</span></span><span >:</span> <span ><span >"</span>/pay<span >"</span></span>,
    <span ><span >"</span>use_cache<span >"</span></span><span >:</span> <span >false</span>
  }
  <span ><span >"</span>related_applications<span >"</span></span><span >:</span> [
    {
      <span ><span >"</span>platform<span >"</span></span><span >:</span> <span ><span >"</span>play<span >"</span></span>,
      <span ><span >"</span>url<span >"</span></span><span >:</span> <span ><span >"</span>https://play.google.com/store/apps/details?id=com.bobpay<span >"</span></span>,
      <span ><span >"</span>fingerprints<span >"</span></span><span >:</span> [{
        <span ><span >"</span>type<span >"</span></span><span >:</span> <span ><span >"</span>sha256_cert<span >"</span></span>,
        <span ><span >"</span>value<span >"</span></span><span >:</span> <span ><span >"</span>59:5C:88:65:FF:C4:E8:20:CF:F7:3E:C8...<span >"</span></span>
      }], <span >//new</span>
      <span ><span >"</span>min_version<span >"</span></span><span >:</span> <span ><span >"</span>1<span >"</span></span>, <span >// new</span>
      <span ><span >"</span>id<span >"</span></span><span >:</span> <span ><span >"</span>com.example.app1<span >"</span></span>
    }, {
      <span ><span >"</span>platform<span >"</span></span><span >:</span> <span ><span >"</span>itunes<span >"</span></span>,
      <span ><span >"</span>url<span >"</span></span><span >:</span> <span ><span >"</span>https://itunes.apple.com/app/example-app1/id123456789<span >"</span></span>,
    }
  ]
}

Within this JSON file is a signature that is used to verify the integrity of the application installed on your device that is claiming to be the real Bob Pay. If this signature check fails, then Bob Pay will not be accepted as a payment handler.

Of course, I am vastly, vastly, vastly, oversimplifying the general process involved here. Payments are an incredibly complex system that require multiple layers of security checks in order to ensure that only valid payments are made. The three documents I linked to earlier outline how the browser fully implements the Payment Request API, how a website implements the JSON manifest file, and how an Android app can handle the intent sent by the Payment Request API. Here is a flowchart that outlines the general process that I summarized above:

Payment flowchart. Source: Rouslan Solomakhin

As you can see, there are a lot of steps involved here. All of these changes will be handled by developers of online merchant websites, Android banking/credit card apps, and developers of web browsers so an end user will likely have no idea what is really going on here. But just know that the end result is that your online payments will become a whole lot simpler if all parties involved implement these changes, which thanks to the standardization efforts of the Web Payments Working Group will hopefully become reality.


The History Behind the Payment Request API

The World Wide Web Consortium (abbreviated W3C) was founded in 1994 in order to develop platform standards that would allow for all websites and their users to benefit from intercompatibility and consistency. In order to address the growing fragmentation of web payments, the W3C formed the Web Payments Working Group in 2015 in order to standardize some aspects of the online payment flow. Thereafter, work began among all members of the Web Payments Working Group in order to find ways to enhance the way existing online payment systems work.

The group came up with the Payment Request API, a collection of methods to allow websites to use payment methods without integrating the payment method into their site. Web browsers need to be updated to support the API, but the more difficult part stems from getting online merchants on board. To that end, members of the Working Group came up with a proposal on how websites can create identifiers to define which payment methods they support. This involves creating a Payment Manifest JSON file that is machine readable (the Payment Method Identifier) - it needs to be read by the browser so the Payment Request API can identify if the user has one or more of the applications corresponding to the supported payment methods identified in the JSON file. This implementation is inspired by Google's Digital Asset Links Protocol which is how websites redirect you from their mobile site to their application if you already have it installed.

After much internal back and forth by the group, eventually on November 25, 2016, Zach Koch from Google and Dapeng Liu from Alibaba submitted an initial draft of the Payment Method Manifest in order to start the standardization process for Payment Method Identifiers that all members could agree to. Eventually, members of the Working Group met in person in Chicago between March 23-24th in order to hash out the Payment Request API, the Payment Manifest Proposal, and more. The Working Group voted to formally adopt a new version of the Payment Manifest Proposal (version 2), which is where we stand today.


Support for the Payment Request API

On May 10th, support for third-party Android payment apps are now enabled by default in Chromium since the web payment manifest prerequisite was approved in the blink-dev branch (Blink is the name of the rendering engine used by Chrome). Note that this feature has been in testing in Chrome for months, but it is only recently that it appears the group is ready to go forward with this. This feature will ship on all platforms/versions of Chromium except for the Android Webview (which does not have a UI and thus cannot implement the Payment Request API).

Only after months of behind the scenes work, are we now going to see the benefits of what the Web Payments Working Group has been working on. At Google I/O, the company is likely to announce that Google Chrome will ship with the Payment Request API enabled, and Zach Koch mentioned earlier will be giving his talk on Thursday about how third party payment providers can support the API by building Payment Manifest JSON files.

Other browsers are also working to add support for the Payment Request API. Mozilla and Samsung have expressed public support for adding the API, though according to Googler Rouslan Solomakhin there's no word yet on if Microsoft's Edge browser or Apple's Safari will add support. We should note that Microsoft is already testing the Payment Request API for Universal Windows Platform (UWP) apps and at least one bank has already implemented support (Monzo) in their app.

As for other online merchants and Android applications that will support this new payment specification, according to Googler Zach Koch:

The number of "payment method providers" that would need to implement this spec is quite small (hundreds), and right now we're only working directly with a very small subset of those (<5) to test the waters. If we did run into a situation where we needed to change one of the fields, I think we could do so easily and without much (if any) interop risk. All of our early partners are aware that this spec can change and are okay with that.

Getting this rolled out is critical for letting other players participate in the PR ecosystem, at least on Android. I'd really prefer to not go down the full proprietary route to enable android native apps. We've kept the footprint on this intentionally small to leave room for growth and more advanced use cases.

Thus, we can see that although Google is pioneering support for the Payment Request API, it will take some time before we truly see this new way to pay find its way into all browsers, all online merchants, and all applications. I personally am very excited to see the Payment Request API become supported by Google. The eCommerce ecosystem has been needlessly fragmented with payment methods for years, and if this new API will mean that I never have to enter my credit card information manually into a website ever again, then I'm all for it.


What do you think of this upcoming standard? Sound off in the comments and let us know your opinion!