> For the complete documentation index, see [llms.txt](https://richnologies.gitbook.io/ngx-stripe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://richnologies.gitbook.io/ngx-stripe/core-concepts/payment-request-button.md).

# 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](https://stripe.com/docs/apple-pay), [Google Pay](https://stripe.com/docs/google-pay), [Microsoft Pay](https://stripe.com/docs/microsoft-pay), and the browser standard [Payment Request API](https://stripe.com/docs/stripe-js/reference#stripe-payment-request).

### Prerequisites

{% hint style="danger" %}
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
{% endhint %}

Please check all the information regarding **prerequisites** in the Stripe Payment Request Button [site](https://stripe.com/docs/stripe-js/elements/payment-request-button#html-js-prerequisites).

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

{% tabs %}
{% tab title="payment-request-button.component.ts" %}

```typescript

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 }
    );
  }
}

```

{% endtab %}

{% tab title="payment-request-button.component.html" %}

```markup
<h2>Payment Request Button</h2>
<ngx-stripe-payment-request-button
  [paymentOptions]="paymentRequestOptions"
  (paymentMethod)="onPaymentMethod($event)"
  (shippingaddresschange)="onShippingAddressChange($event)"
  (notavailable)="onNotAvailable()"
></ngx-stripe-payment-request-button>
```

{% endtab %}
{% endtabs %}

### 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
