Getting Paid with the Payment-Request API
This post first appeared on the Samsung Internet blog pages
The whirlwind of 2020 has blown many people out of work and steady employment. It’s also brought with it uprisings, protests and I’m sure we’re on the verge of a revolution somewhere 👀. But with these changes, there have also been people dedicating more time to their side-hustles, new organisations dedicated to activism and community good, and more established organisations who’ve seen a boom in their donations this year. While many will rely on a combination of direct bank/PayPal transfer or whatever payment processor comes with their site builder, some will need to roll out their own payment processing. This is exactly the situation Laura and I found ourselves in as we’re building out the Samsung Global Goals PWA and this is where the Payment Request API comes into play.
The Payment Request API is a secure way to collect payments from users without having to collect and store any of their personal details yourself (this is subject to regional laws, make surer you’re following regulation when handling customer data and money), it “provides a consistent user experience for both merchants and users”. You’ve likely used this API when you bought those cute masks on Etsy and paid with Samsung/Google/Apple pay. On a desktop web browser, the API will use the browser’s cards however, in a mobile browser the API will use Google/Samsung Pay instead. This is what that looks like:
A Basic Setup
You absolutely should be using a payment processor and shouldn’t be rolling out your own, so for this I’m using Stripe. Stripe does a good job of abstracting a lot of the nitty gritty of the Payment Request API but still keeps some of the key functions. This basic set up took me a moment to get my head around because of the back and forth between the server and the client. Considering we’ve had enough confusion to last two lifetimes this year, I thought to break the process down and share it.
- First create and show the payment request in the client, this brings up the form.
/* CLIENT */const paymentRequest = **_stripe_**.paymentRequest({
country: 'GB',
currency: 'gbp',
total: {
label: 'Donation',
amount: 100,
},
requestPayerName: true,
requestPayerEmail: true
});await paymentRequest.canMakePayment()
paymentRequest.show();
- In the server, create a Stripe payment intent and send the client secret from the intent to client
/* SERVER */app.get('/payment/', async(req,res)=>{ const paymentIntent = await stripe.paymentIntents.create({
amount: 100,
currency: 'gbp',
payment_method_types: ['card']
}); res.send({clientSecret: paymentIntent.client_secret});})
- Use the payment intent’s client secret to confirm the card payment
/* CLIENT */const fetchedClientSecret = await fetch(`/payment`);
const clientSecretObj = await fetchedClientSecret.json();paymentRequest.on('paymentmethod', async (ev) => {
const {paymentIntent, error: confirmError} = await **_stripe_**.confirmCardPayment(
clientSecretObj.clientSecret,
{payment_method: ev.paymentMethod.id},
{handleActions: false}
); if (confirmError) {
ev.complete('fail');
} else {
ev.complete('success');
}
});
What do You Get Out of it?
The greatest benefit of the Payment Request API is that it simplifies the payment flow while also ensuring security, but there are more reasons:
- You don’t need to create your own checkout form.
- You don’t need to store any user details, this is particularly useful for those collecting one-off payments. The payer’s details such as name, email, address, etc are forwarded straight to the payment processor i.e. Stripe depending on the card info that’s stored in the browser. The exception to this is with Apple Pay, where you need to provide a name/email/phone number to also get the address attached to the card, you can do this in one or two lines:
const paymentRequest = stripe.paymentRequest({
... **requestPayerName: true,
requestPayerEmail: true**
});
- It’s a consistent user experience across compatible browsers.
- Validation, localisation and accessibility are all handled for you.
- It only works over HTTPS.
- Stripe, Braintree and other payment processors have integrated it into their APIs.
Limitations
- If you absolutely do need to track payments in your system, you’ll still need to collect their personal details (name, email, etc).
- If you’re using Stripe, getting your head around the flow of data between the client may be a bit confusing initially.
In Summary…
I’m a convert and I hope you are too. The Payment Request API does a lot of heavy lifting so you don’t have to, paired with a good payment processor then you really don’t have to worry about collecting secure payments that are easily traceable (for audits) and stored safely.