This tutorial is out of date and no longer maintained.
Stripe recently released Stripe Elements, a set of UI elements that make it easy to build a custom checkout flow, complete with real-time validation and autocomplete support. In this post, we’ll go over the basics of integrating Stripe and Stripe Elements on the frontend with Angular.
We’ll create a simple payment form that gets a token from the Stripe API. Stripe’s documentation for Elements is for integrating using vanilla JavaScript, but here we’ll modify this implementation slightly to integrate with an Angular template-driven form.
First, in your project’s index.html
file, you’ll want to add and initialize Stripe.js
as well as initialize Stripe Elements:
Warning: Remember to change to your live publishable key once your app goes to production.
Since Stripe.js
is added outside the scope of the project and doesn’t have typings, TypeScript would normally complain when trying to access stripe
or elements
. To fix this, we’ll add two declarations to the project’s typings.d.ts
file:
We’ll be using Angular’s template-driven forms for our simple payment form, so we also have to import the FormsModule in our app or feature module:
The template markup for a basic checkout flow is as simple as it gets:
The #card-info
element will be the container for the Stripe Elements, and we also created a container div to display error messages, if any.
The fun part starts when we hook everything up in the component class. Here’s the code to make our example work, with some interesting parts highlighted:
There may seem to be a lot doing on at first glance, but it’s all really straightforward. Here are a few things to note:
ViewChild
decorator.onChange
method to the this
of the class and save the new reference as cardHandler
. This reference is used to add an event listener when the card element is created and remove it in the OnDestroy
hook.card
element in the AfterViewInit
lifecycle hook, to ensure that our container element is available.ChangeDetectorRef
to manually instruct Angular to run a change detection cycle in the onChange
method.onSubmit
, is an async function that await
s for Stripe’s createToken
promise to resolve.OnDestroy
we clean up by removing the change event listener and destroying the card element.Our example is really barebones, but in a real app, you’ll want to also implement a simple boolean flag that prevents the user from submitting the form multiple times in a row. For example, the submit button could be replaced by a loading indicator from the time the form is submitted up until your backend sends a success message indicating that the charge was processed. In that case, you’d redirect the user to something like a confirmation page.
Note: To test things out, use card number 4242 4242 4242 4242
with any expiration date in the future, any 3-digit number for the CVC, and any valid zip code.
We have a simple checkout form working, but it looks pretty dull. Let’s add a touch of styles. First, let’s style our form and submit button:
The Stripe card element itself can be styled using selectors like .StripeElement
, .StripeElement--focus
and .StripeElement--invalid
. There are a few ready-made theme examples available, but here we’ll just add the default style provided by Stripe:
Some basic styles can also be passed-in with an option object as a second argument to the create method:
You can refer to the options API reference for a list of all the possible style configuration options.
Our checkout form is all well and good, but what if we also want to save some additional data for the customer in Stripe? It’s as simple as passing a second argument to createToken
with any extra field.
Here for example we also send the email address for the customer:
In this post, you created a form using the Stripe API and Stripe Elements with an Angular template-driven form.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
The Pay Button is missing from the document also many unwanted scripts are there in the app.component.html section