Payment Request Button

Collect payment and address information from customers who use Apple Pay, Google Pay, Microsoft Pay, and the Payment Request API.

The Payment Request Button Element gives you a single integration for Apple Pay, Google Pay, Microsoft Pay, and the browser standard Payment Request API.

Prerequisites

Add a payment method to your browser.

Serve your application over HTTPS, both in development and production

For Apple Pay you will need to verify your domain, both in development and production

Please check all the information regarding prerequisites in the Stripe Payment Request Button site.

After that, you can use the built-in component. Here is a complete example:


import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

import { StripeService } from 'ngx-stripe';
import {
  StripeElementsOptions,
  PaymentRequestPaymentMethodEvent,
  PaymentIntent,
  PaymentRequestShippingAddressEvent,
} from '@stripe/stripe-js';

@Component({
  selector: 'app-payment-request-button',
  templateUrl: './payment-request-button.component.html',
})
export class PaymentRequestButtonComponent {
  elementsOptions: StripeElementsOptions = {
    locale: 'es',
  };

  paymentRequestOptions = {
    country: 'ES',
    currency: 'eur',
    total: {
      label: 'Demo Total',
      amount: 1099,
    },
    requestPayerName: true,
    requestPayerEmail: true,
  };

  constructor(
    private http: HttpClient,
    private stripeService: StripeService
  ) {}

  onPaymentMethod(ev: PaymentRequestPaymentMethodEvent) {
    this.createPaymentIntent()
      .pipe(
        switchMap((pi) => {
          return this.stripeService
            .confirmCardPayment(
              pi.client_secret,
              { payment_method: ev.paymentMethod.id },
              { handleActions: false }
            )
            .pipe(
              switchMap((confirmResult) => {
                if (confirmResult.error) {
                  // Report to the browser that the payment failed, 
                  // prompting it to re-show the payment interface, 
                  // or show an error message and close the payment.
                  ev.complete('fail');
                  return of({
                    error: new Error('Error Confirming the payment'),
                  });
                } else {
                  // Report to the browser that the confirmation was 
                  // successful, prompting it to close the browser 
                  // payment method collection interface.
                  ev.complete('success');
                  // Let Stripe.js handle the rest of the payment flow.
                  return this.stripeService.confirmCardPayment(
                    pi.client_secret
                  );
                }
              })
            );
        })
      )
      .subscribe((result) => {
        if (result.error) {
          // The payment failed -- ask your customer for a new payment method.
        } else {
          // The payment has succeeded.
        }
      });
  }

  onShippingAddressChange(ev: PaymentRequestShippingAddressEvent) {
    if (ev.shippingAddress.country !== 'US') {
      ev.updateWith({ status: 'invalid_shipping_address' });
    } else {
      // Replace this with your own custom implementation if needed
      fetch('/calculateShipping', {
        data: JSON.stringify({
          shippingAddress: ev.shippingAddress,
        }),
      } as any)
        .then((response) => response.json())
        .then((result) =>
          ev.updateWith({
            status: 'success',
            shippingOptions: result.supportedShippingOptions,
          })
        );
    }
  }

  onNotAvailable() {
    // Subscribe to this event in case you want to act
    // base on availability
    console.log('Payment Request is not Available');
  }

  createPaymentIntent(): Observable<PaymentIntent> {
    // Replace this with your own custom implementation 
    // to perform a Payment Intent Creation
    // You will need your own Server to do that
    return this.http.post<PaymentIntent>(
      '/create-payment-intent',
      { amount: this.paymentRequestOptions.total.amount }
    );
  }
}

Outputs

The component has a couple of Outputs you can subscribe. The ones in the example are the most important ones, but here is a complete list:

  • token

  • paymentMethod

  • cancel

  • shippingaddresschange

  • shippingoptionchange

  • notavailable

Last updated