![Eiji Kitamura](https://web.dev/images/authors/agektmr.jpg) Eiji Kitamura [X](https://twitter.com/agektmr) [GitHub](https://github.com/agektmr) [Mastodon](https://infosec.exchange/@agektmr) [Bluesky](https://bsky.app/profile/agektmr.com)

<br />

When a customer tries to purchase something from your website, the site must ask
the customer to provide payment information and, optionally, other information
such as shipping preference. You can achieve this and quickly using the
[Payment Request API (PR API)](https://w3c.github.io/payment-request/).

## Basic payment structure

Constructing a `PaymentRequest` object requires two parameters: *payment
methods* and *payment details* . In addition, a third *payment options* parameter
is optional. A basic request could be created like this:

    const request = new PaymentRequest(paymentMethods, paymentDetails);

Take a look at how each parameter is built and used.

### Payment methods

The first parameter, *paymentMethods* , is a list of supported payment methods in
an array variable. Each element in the array comprises two components,
`supportedMethods` and, optionally, `data`.

For `supportedMethods`, the merchant needs to specify a [Payment Method
Identifier](https://web.dev/articles/setting-up-a-payment-method#step_1_provide_the_payment_method_identifier)
such as `https://bobbucks.dev/pay`. The existence and content of `data` depends on
the content of `supportedMethods` and payment app provider's design.

Both pieces of information should be provided by the payment app provider.

    // Supported payment methods
    const paymentMethods = [{
      supportedMethods: 'https://bobbucks.dev/pay',
      data: {
        ... // Optional parameters defined by the payment app provider.
      }
    }];

### Payment details

The second parameter, *paymentDetails* , is passed as an object and specifies
payment details for the transaction. It contains the required value `total`,
which specifies the total amount due from the customer. This parameter can also
optionally list the purchased items.

In the following example, the optional purchased items list (just one item, in this
case) is shown, as is the required total amount due. In both cases the currency
unit is specified with each individual amount.

    const paymentDetails = {
      displayItems: [{
        label: 'Anvil L/S Crew Neck - Grey M x1',
        amount: { currency: 'USD', value: '22.15' }
      }],
      total: {
        label: 'Total due',
        amount: { currency: 'USD', value : '22.15' }
      }
    };

## Check whether the payment method is available

Chrome checks whether the user and the environment are ready for making payment
during the construction of a `PaymentRequest` object.

To check if the user and the environment are ready for making a payment, call
`canMakePayment()` before invoking the payment procedure. Calling
`canMakePayment()` returns `true` if the browser supports at least one payment
method specified in the object.

    request.canMakePayment().then(result => {
      if (result) {
        // This browser supports the specified payment method.
      } else {
        // This browser does NOT support the specified payment method.
      }
    }).catch(e => {
      // An exception
    });

Learn more about [PaymentRequest.canMakePayment() on MDN](https://developer.mozilla.org/docs/Web/API/PaymentRequest/canMakePayment)

## The `show()` method

After setting the two parameters and creating the `request` object, you can call
the `show()` method, which displays the payment app user interface.

> [!WARNING]
> **Warning:** To call the `show()` method, you must add a [user activation](https://developer.chrome.com/blog/user-activation). This means the call must be inside an event listener, such as `click`. Note that Chrome [enforces this constraint from version 102](https://chromestatus.com/feature/5948593429020672).

    request.show().then(response => {
      // [process payment]
      // send to a PSP etc.
      response.complete('success');
    });

> [!NOTE]
> **Note:** `basic-card` payment method is deprecated from Chrome 100. If the browser doesn't support any of the specified payment methods, it will throw `NotSupportedError`. Make sure to first check the payment method availability with `canMakePayment()`.

How payment app user interface will look is completely up to the payment app
provider. After the customer agrees to make a payment, a JSON object is passed
to the merchant which contains all the required information to transfer money.
The merchant can then send it to the PSP to process the payment.

Finally, you may close the Payment Request UI by completing the process with
`response.complete('success')` or `response.complete('fail')` depending on the
result that the PSP returns.

## Next up

Learn more about [Web Payments](https://web.dev/explore/payments).