Serverless and Stripe payment intents
Small log today to just talk about a snag I ran into integrating Stripe into the serverless stack following :
Working with 3rd Party APIs
So far we've created a basic CRUD (create, read, update, and delete) API. We are going to make a small addition to this…
While not strictly needed if you’re in the US but:
On September 14, 2019, Strong Customer Authentication (SCA) took effect in Europe. Under this regulation, card payments require additional authentication. Transactions that don’t follow the new guidelines may be declined.
I know this because it bit us hard in our own app where we had micropayments in a time-sensitive situation. So I wanted to follow that learning and use the payment intents stuff from Stripe.
Of course… I haven’t used serverless before and i didn’t do the backend work last time. A rod for my own back, but one I enjoyed hacking away at and reading about. I learn the most when I’m breaking things constantly.
npm install stripe
Seen a few ways to do this when looking about but this is it.
import Stripe from 'stripe';
Generate your instance
The apiVersion is actually quite a clever typing to keep you up to date, it fails to build if Stripe is upgraded and you haven’t updated this here (unless you use null of course).
typescript: true simply sets your agent to Typescript for now. Seemed like I should… 😅
Generate a payment intent
To help you a little this always made it clearer what the flow was in a payment intent checkout.
To summarise :
- We generate a payment intent on the API side via Stripe
- We send this to the client app
- The client app will use the secret and key to complete a transaction directly with stripe
- Stripe will return a succeeded. Also incidentally not included in this flow, it will fire to a webhook too on the API. This is useful if you need to change some state to reflect the transaction was a success e.g. trigger shipping.
Something I ran into here you might notice was the ESLINT rules were too strict here. It did not approve of snake case… but I couldn’t be bothered to do rule configuration just yet so a little ignore comment to let me carry on.
Sending the payment intent back to the client along with our publishable key and an amount that the user is being charged.
I return the
amount here, which incidentally is a custom billing functions output in pence. So that the client will be able to surface the actual amount the customer is going to pay.
Technically you could take the charge and you’re done but I wanted to make sure I’d be able to configure Stripe to call me back after the user pays (or if it was a failed payment).
I’m not going to go into detail, the code is pretty straightforward and also this is as yet untested 😀. I’ve only just made it but I’ve tested it locally as far as validating it will throw an error while the signature check is invalid.
The output is a success after that regardless, and I’ve got nothing to do with it yet, I just wanted to have it ready.
Some things I’ll need to do going forward:
- Make it easier to test — the signature thing is a pain.
- Setup some logging so I can see this working on my side.
- Change the ES-Lint rules, they’re a little strict for ‘learning’… no-console especially 😿
If anyone who has done this more than I see anything misinformative please comment and I’ll be sure to correct ASAP. This is just scratching the surface for me, I expect when I come to implement the front-end with Stripe Elements I’ll learn what I’ve done wrong and have to come back here and update then.