Payment Element


The Payment Element is a versatile, embeddable component designed for securely collecting payment details. It supports numerous payment methods through a single, streamlined integration. The Payment Element simplifies the construction of both an embedded and customized payments experience, suitable for a variety of payment types.

For detailed information about the Payment Element and its usage, refer to the official Stripe documentation.

This guide focuses on utilizing the Payment Element within an Angular framework using ngx-stripe. Similar to other Stripe Elements, ngx-stripe offers a comparable API. Below is an example demonstrating how to collect card payments using the Payment Element.

Using Stripe Elements Directive

To integrate the Payment Element with ngx-stripe, it is recommended to wrap the Payment Element component using the Stripe Elements Directive. For a detailed guide on the Stripe Elements Directive, visit the Stripe Elements section.

        <div [formGroup]="paymentElementForm">
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="name" formControlName="name" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="Email" type="email" formControlName="email" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="Address" formControlName="address" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="ZIP Code" formControlName="zipcode" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="city" formControlName="city" />
  </mat-form-field>
  @if (elementsOptions.clientSecret) {
    <ngx-stripe-elements
      [stripe]="stripe"
      [elementsOptions]="elementsOptions"
    >
      <ngx-stripe-payment [options]="paymentElementOptions" />
    </ngx-stripe-elements>
  }
  <button (click)="pay()">PAY</button>
</div>
      

Implicit Elements Option

Alternatively, the Payment Element can be used through implicit elements, where you directly pass the Stripe instance and element options, and they are internally created. Note, this approach is deprecated and preserved mainly for backward compatibility.

        <div [formGroup]="paymentElementForm">
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="name" formControlName="name" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="Email" type="email" formControlName="email" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="Address" formControlName="address" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="ZIP Code" formControlName="zipcode" />
  </mat-form-field>
  <mat-form-field class="example-full-width" appearance="fill">
    <input matInput placeholder="city" formControlName="city" />
  </mat-form-field>
  @if (elementsOptions.clientSecret) {
    <ngx-stripe-payment
      [stripe]="stripe"
      [elementsOptions]="elementsOptions"
      [options]="paymentElementOptions"
    />
  }
  <button (click)="pay()">PAY</button>
</div>
      

Fetch Updates and Update

To synchronize the Payment Element with the latest data from the associated PaymentIntent or SetupIntent, utilize the fetchUpdates method. This can be executed through either the Payment Element component or the Elements Directive.

Additionally, you can imperatively update the Payment Element by invoking the update method.

        import { Component, inject, ViewChild } from '@angular/core';
import { UntypedFormBuilder, Validators } from '@angular/forms';

import { MatInputModule } from '@angular/material/input';

import {
  injectStripe,
  StripeElementsDirective,
  StripePaymentElementComponent
} from 'ngx-stripe';
import {
  StripeElementsOptions,
  StripePaymentElementOptions
} from '@stripe/stripe-js';

@Component({
  selector: 'ngstr-checkout-form',
  templateUrl: './payment-element.component.html',
  standalone: true,
  imports: [
    ReactiveFormsModule,
    MatInputModule,
    StripeElementsDirective,
    StripePaymentElementComponent
  ]
})
export class CheckoutFormComponent {
  @ViewChild(StripePaymentElementComponent)
  paymentElement!: StripePaymentElementComponent;
  @ViewChild(StripeElementsDirective)
  elements!: StripeElementsDirective;

  private readonly fb = inject(UntypedFormBuilder);

  paymentElementForm = this.fb.group({
    name: ['John doe', [Validators.required]],
    email: ['[email protected]', [Validators.required]],
    address: [''],
    zipcode: [''],
    city: [''],
    amount: [2500, [Validators.required, Validators.pattern(/d+/)]]
  });

  elementsOptions: StripeElementsOptions = {
    locale: 'en',
    appearance: {
      theme: 'flat',
    },
    clientSecret: '{{ YOUR_CLIENT_SECRET }}'
  };

  paymentElementOptions: StripePaymentElementOptions = {
    layout: {
      type: 'tabs',
      defaultCollapsed: false,
      radios: false,
      spacedAccordionItems: false
    }
  };

  stripe = injectStripe({{ YOUR_STRIPE_PUBLIC_KEY }});

  fetchUpdates() {
    this.paymentElement.fetchUpdates();
  }

  // It's the same method as above. Just to show that you can use it on the elements directive
  fetchUpdatesFromElements() {
    this.elements.fetchUpdates();
  }

  update(options: Partial<StripePaymentElementOptions>) {
    this.paymentElement.update(options);
  }
}
      

Collapse Method

The collapse method is exclusively available for the Payment Element component. It allows you to conceal parts of the element from view.

        import { Component, inject, ViewChild } from '@angular/core';
import { UntypedFormBuilder, Validators } from '@angular/forms';

import { MatInputModule } from '@angular/material/input';

import {
  injectStripe,
  StripeElementsDirective,
  StripePaymentElementComponent
} from 'ngx-stripe';
import {
  StripeElementsOptions,
  StripePaymentElementOptions
} from '@stripe/stripe-js';

@Component({
  selector: 'ngstr-checkout-form',
  templateUrl: './payment-element.component.html',
  standalone: true,
  imports: [
    ReactiveFormsModule,
    MatInputModule,
    StripeElementsDirective,
    StripePaymentElementComponent
  ]
})
export class CheckoutFormComponent {
  @ViewChild(StripePaymentElementComponent)
  paymentElement!: StripePaymentElementComponent;

  private readonly fb = inject(UntypedFormBuilder);

  paymentElementForm = this.fb.group({
    name: ['John doe', [Validators.required]],
    email: ['[email protected]', [Validators.required]],
    address: [''],
    zipcode: [''],
    city: [''],
    amount: [2500, [Validators.required, Validators.pattern(/d+/)]]
  });

  elementsOptions: StripeElementsOptions = {
    locale: 'en',
    appearance: {
      theme: 'flat',
    },
    clientSecret: '{{ YOUR_CLIENT_SECRET }}'
  };

  paymentElementOptions: StripePaymentElementOptions = {
    layout: {
      type: 'tabs',
      defaultCollapsed: false,
      radios: false,
      spacedAccordionItems: false
    }
  };

  stripe = injectStripe({{ YOUR_STRIPE_PUBLIC_KEY }});

  collapse() {
    this.paymentElement.collapse();
  }
}