Integrating the Payment Request API with a payment service provider

With the Payment Request API, payments on the web are drastically simplified. The UX can be consistent across websites, making it easier for users to enter and reuse their personal information such as shipping address or payment details. It also enables various payment methods on the web.

Let me quickly recap important payment concepts:

basic card — A payment method natively implemented to all Payment Request API capable browsers (Chrome, Samsung Internet, Edge). Card information is usually shared with form autofill data and returned as plain text from the Payment Request API.

payment app — A web app or a native app that provide payment methods represented as URL strings. Pay with Google, Apple Pay, Samsung Pay, Alipay are good examples. Card information is securely stored and typically returned as a tokenized text from the Payment Request API.

The Payment Request API changes whole ecosystem, but it’s not a silver bullet that takes care of payments end to end including processing. It’s a very common misconception, but you still need to deal with payment service providers (PSP).

Google’s Payment Request API documentation describes the API in detail, but leaves integration with a PSP part untouched. In this article, I’d like to give you ideas of how to integrate with a PSP.

For simplicity’s sake, I’ll focus on the credit card payment (basic-card) case in this article. This article may not apply to other payment methods, such as Pay with Google, Apple Pay, Samsung Pay, and Alipay.

What’s the current payment experience and integration like?

When you try to pay online using a credit card, you usually see a web form like this:

This form includes fields for cardholder name, card number, expiration year/date, and CVC code. By submitting this form, the merchant will receive these pieces of information to process the payment on behalf of the user.

Behind the scenes, most of the merchants send these information to a payment gateway or a payment processor (PSP, Payment Service Providers in this article) in order to process a payment and make an actual money transfer start.

There are roughly three types of integration patterns you can choose to connect with a PSP in general. Let’s see how each of them look like.

API Type Integration

The first integration pattern is called API Type. It’s straightforward, but requires relatively high technical skill to implement.

A merchant submits credit card information to their own server through a form. The server then forwards the information to a PSP through their API. PSPs usually provide a server side SDK to help implement these integrations.

Link Type Integration

Link Type is the easiest way to integrate with a PSP among three. Though flexibility of design and its user experience are not sophisticated, even a non-technical webmaster can integrate with a PSP using this type.

When a user is about to make a payment, the merchant forwards the user to a PSP-hosted page with a form to accept credit card information. The payment info the user submits through the form will be directly passed to and processed by the PSP. The user will then be brought back to the merchant webpage to (hopefully) find the payment is complete.

Tokenization Type Integration

The most modern approach among these three is Tokenization Type. This integration allows a merchant to gain security, convenience, and design flexibility at the same time.

Unlike Link Type, a form is shown in a merchant hosted page, but it’s actually served from a PSP’s domain through an iframe. User’s submission of card info will be directly passed to the PSP’s server, and the merchant will receive a token as a result. The merchant can then verify it through their server and ask the PSP to process the payment.

The point here is that most of these operations are handled by PSP’s client side SDK, which allows the merchant to process payments without touching a single digit of a user’s credit card number.

How can this be applied to the Payment Request API?

OK, now let’s think about how these patterns can be applied with the Payment Request API. Here’s a snippet of code you would use to invoke the API:

let request = new PaymentRequest(methods, details, options);
request.show().then(paymentResponse => {
// process payment
});

Upon the user pressing “PAY”, the payment request will be resolved and you will receive a paymentResponseas the payment information. If the user chooses to use a basic-card as a payment method, it would look like this:

{
"methodName": "basic-card",
"details": {
"cardholderName": "Jane Doe",
"cardNumber": "4242424242424242",
"expiryMonth": "12",
"expiryYear": "2020",
"cardSecurityCode": "111",
"billingAddress": { ... }
},
"shippingAddress": null,
"shippingOption": null,
"payerName": null,
"payerPhone": null,
"payerEmail": null
}

You can then use the payment information part of it (details) to process the payment.

Let’s apply this information to the integration patterns I have described earlier.

API Type

This pattern is rather straightforward. Just send the payment info to the server, parse it, and then send it to a PSP’s API.

The important caveat here is that you need PCI compliance to integrate using this type, because you are obviously treating raw credit card information. PCI SAQ A won’t qualify, you should have PCI SAQ A-EP or PCI DSS. If you don’t know what I’m talking about, consult with your PSP. Unless your company is large enough, spends money and makes an effort to comply with PCI, you are not eligible to choose this option (except some countries that don’t prioritize PCI DSS).

Link Type

As you can easily imagine, the point of Link Type is to decouple the payment system from a merchant website. This means using the Payment Request API with the Link Type integration is theoretically not possible. You have to defer the Payment Request API calls to your PSP.

Tokenization Type

The Tokenization Type pattern is an interesting one. With this integration, you would send payment information to a PSP server to obtain a token in return. This allows your server to not deal with raw credit card information completely, keeping you away from requiring PCI compliance — unfortunately, this is wrong.

The fact that handling credit card information on the client side doesn’t require PCI compliance was a thing before PCI 3.1. PCI DSS 3.2 clarified it requires PCI SAQ A-EP or PCI DSS if you handle raw credit card info on the client side. In fact, the reason the Tokenization Type is so complex is to align with the easiest option for PCI (SAQ A) and never make a merchant touch such sensitive information, but yet enable them to integrate with their system.

OK, then, what does this mean to you? This means, in order to implement the Payment Request API with basic card, a merchant ought to be PCI compliant, otherwise defer it to a PSP.

In fact, some PSPs already started supporting the Payment Request API as part of their Pay with Google support (ex: Stripe, Braintree).

Conclusion

In order to bring the Payment Request API and let users see the Payment Request sheet on your website, you have two options:

  • If you have PCI compliance (PCI SAQ A-EP or PCI DSS), implement the Payment Request API yourself using the API Type integration.
  • If you don’t have PCI compliance (or PCI SAQ A), wait for your PSP to support the Payment Request API and use it through the Link Type integration or via their SDK as the Tokenization Type integration.

Some people may be disappointed to find that PCI compliance is still a requirement to implement the Payment Request API. But consider this is a path to the brighter future.

In the next post, I will describe how basic card is positioned, why it’s needed, what are payment apps and what the future would look like.

Special thanks to my colleagues and Daniel Heffernan from Stripe for reviewing this post.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.