Integrating Stripe Elements with Angular | Task

Ole Ersoy
Mar - 22  -  3 min

Scenario

During checkout we want to obtain a checkout token from Stripe using Stripe Elements and Angular.

Approach

Stackblitz

Go to stackblitz and start a brand new Angular project. Delete the hello.component.ts and remove it from app.module.ts.

Also remove the <hello name=”{{ name }}”></hello> from app.component.html.

Dependencies

Add @fireflysemantics/angular-stripe-service to the Stackblitz dependencies.

Initialize Stripe Elements

Constructor inject the AngularStripeService into app.component.ts.

import { AngularStripeService } from '@fireflysemantics/angular-stripe-service';
constructor(
    private cd: ChangeDetectorRef,
    private stripeService:AngularStripeService) {}

Initialize stripe elements:

ngAfterViewInit() {
this.stripeService.setPublishableKey('pk_test_2syov9fTMRwOxYG97AAXbOgt008X6NL46o').then(
stripe=> {
   this.stripe = stripe;
   const elements = stripe.elements();
   this.card = elements.create('card');
   this.card.mount(this.cardInfo.nativeElement);
   this.card.addEventListener('change', this.cardHandler);
});
}

Note that key pk_test_2syov9fTMRwOxYG97AAXbOgt008X6NL46o is a temporary key used for this demo. You will need to provide your own.

Import the Form Module

In app.module.ts:

import {FormsModule} from '@angular/forms';

Markup

Put the following markup in app.component.html:

<form #checkout="ngForm" (ngSubmit)="onSubmit(checkout)" class="checkout">
<div class="form-row">
<label for="card-info">Card Info</label>
<div id="card-info" #cardInfo></div>
<div id="card-errors" role="alert" *ngIf="error">{{ error }}</div></div>
<button type="submit">Pay $5</button>
</form>

CSS

Add the CSS to app.component.css:

form.checkout {
    max-width: 500px;
    margin: 2rem auto;
    text-align: center;
    border: 2px solid #eee;
    border-radius: 8px;
    padding: 1rem 2rem;
    background: white;
    font-family: monospace;
    color: #525252;
    font-size: 1.1rem;
}
form.checkout button {
    padding: 0.5rem 1rem;
    color: white;
    background: coral;
    border: none;
    border-radius: 4px;
    margin-top: 1rem;
}
form.checkout button:active {
    background: rgb(165, 76, 43);
}

Demo

Analysis

The @fireflysemantics/angular-stripe-service service injects the Stripe scripts for us and waits for it to load before attempting to initialize elements.

The reason this is important is that if our component containing the Stripe form is loaded before Stripe has a chance to initialize elements then the form will not paint correctly.

In other words the Stripe API download and subsequent elements construction is racing the construction of the credit card form component.

If the form component wins that race, the component does not get constructed right, because elements is not yet available.