# Payment Widget

import { Aside, Steps } from "@astrojs/starlight/components";
import CardWidget from "@components/content/CardWidget.astro";

The Payment Widget, available to all SumUp merchants, simplifies website checkouts while handling PCI and PSD2 compliance with flexible customization options. It collects card and alternative payment method details. For card payments, it dynamically recognizes the brand and shows the relevant brand icon.

A secure HTTPS connection is used to submit the payment information. For production usage we only support HTTPS for the payment page. (note: [during development browsers will treat `localhost` as secure](https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Secure_Contexts#potentially_trustworthy_origins)).

## Prerequisites

Payment Widget requires only the ability to create online checkouts via [SumUp checkout API](/api/checkouts/create), authorized by API key or access token (see the [Authorization Guide](/tools/authorization/) for details).​

## Compliance

### Payment Card Industry

The Payment Widget ensures PCI compliance for your business. You do not need to worry about storing or sending sensitive information, such as card details, to SumUp servers.

### Payment Services Directive 2

Strong Customer Authentication (SCA) under Payment Services Directive 2 (PSD2) requires two-factor authentication for European online payments. The widget supports 3D Secure, with bank fallback to 3D Secure 1 in case the customer's bank doesn't support 3DS 2, adding security layers like bank redirects, SMS codes, or app confirmation. Regardless of the 3DS version used, the customer is provided with a seamless checkout experience.

## Integration

<Steps>

1. In order to integrate the Payment Widget on your website, include the `sdk.js` script on your payment page.

   ```js
   <script src="https://gateway.sumup.com/gateway/ecom/card/v2/sdk.js"></script>
   ```

2. Once the script is loaded, you have access to a global variable `SumUpCard`, with a `mount` method which renders the available payment methods.

3. [Create a checkout](/api/checkouts/create) and copy the returned `id`.

4. Pass the returned `id` from the checkout response to the widget component.

   ```html
   <div id="sumup-card"></div>
   <script
     type="text/javascript"
     src="https://gateway.sumup.com/gateway/ecom/card/v2/sdk.js"
   ></script>
   <script type="text/javascript">
     SumUpCard.mount({
       id: "sumup-card",
       checkoutId: "2ceffb63-cbbe-4227-87cf-0409dd191a98",
       onResponse: function (type, body) {
         console.log("Type", type);
         console.log("Body", body);
       },
     });
   </script>
   ```

   The Payment Widget makes a request to execute the checkout and after the request is completed, you get a response based on the callback function configured. As a result of successful integration, you can see the following component:

   <CardWidget />

</Steps >

## Configurations

The Payment Widget allows you to customize certain properties on the card display, as listed below. If you wish to override the default settings, add your own configuration property-value pairs to the `SumUpCard.mount` method.

```js
SumUpCard.mount({
  checkoutId: "...",
  // 'config-name': 'config-value'
});
```

| Property Name            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Value                                                                                                                                                                                                                                                                                                                                                                                                        | Default Value      | Required |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | -------- |
| `checkoutId`             | The unique ID you receive once you [create a checkout](/online-payments/guides/single-payment/#1-create-a-checkout).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `string`                                                                                                                                                                                                                                                                                                                                                                                                     | _no default value_ | yes      |
| `onResponse`             | The callback function that will be called when you receive a response from the payment form. The first parameter is one of the following: <ul><li>`sent` - the form is sent to the server for processing. The second parameter contains information about the last four digits of the card's number and the card's scheme. </li><li>`invalid` - trying to submit the form but there are validation errors.</li><li>`auth-screen` - the user is prompt to authenticate the payment.</li><li>`error` - the server responded with error. The second parameter gives more information about the error.</li><li>`success` - successful result returned by the checkout endpoint **which does not always mean the transaction was successful**. We recommend verifying the [checkout status](/api/checkouts/get) on your server. The second parameter contains the response from the [endpoint](/api/checkouts/process).</li><li>`fail` - failed result returned by the checkout endpoint, can occur when the user cancels the payment form or the session has timed out.</li></ul> | `function`                                                                                                                                                                                                                                                                                                                                                                                                   | `null`             | no       |
| `onLoad`                 | The callback function that will be called when the card widget is loaded.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | `function`                                                                                                                                                                                                                                                                                                                                                                                                   | `null`             | no       |
| `onPaymentMethodsLoad`   | The callback is called when the payment methods are loaded for the given `checkoutId`. Usually used for when the host page needs to change depending on the payment methods available. <br/><br/>Payment methods can be filtered in order to limit those shown by the widget. `return` the list of payment methods for the widget to render as an _Array of Strings_. E.g. to show only Boleto, when available: `() => ['boleto']`;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | `function`                                                                                                                                                                                                                                                                                                                                                                                                   | `null`             | no       |
| `onChangeInstallments`\* | The callback function that will be called when the user changes the dropdown for installments. The first and only parameter will be the number of selected installments. (`showInstallments` must be enabled).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | `function`                                                                                                                                                                                                                                                                                                                                                                                                   | `null`             | no       |
| `showSubmitButton`       | Displays or hides the form's submit button.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `boolean`                                                                                                                                                                                                                                                                                                                                                                                                    | `true`             | no       |
| `showFooter`             | Displays or hides "Powered by SumUp" label.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `boolean`                                                                                                                                                                                                                                                                                                                                                                                                    | `true`             | no       |
| `showInstallments`\*     | Displays or hides a dropdown for choosing installments. Once enabled this overrides any value of the configuration `installments` and will not display `amount` on the submit button.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | `boolean`                                                                                                                                                                                                                                                                                                                                                                                                    | `false`            | no       |
| `showZipCode`\*\*        | Displays or hides ZIP code input field. It is mandatory for merchant users from USA.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | `boolean`                                                                                                                                                                                                                                                                                                                                                                                                    | `false`            | no       |
| `showEmail`              | Displays or hides email input field. At some time in the future it'll be a mandatory field for every integrator because of the <a href="https://en.wikipedia.org/wiki/Strong_customer_authentication" target="_blank" rel="noopener noreferrer">SCA</a>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `boolean`                                                                                                                                                                                                                                                                                                                                                                                                    | `false`            | no       |
| `email`                  | Alternative way (to `showEmail`) to pass user's email if for example you know it from a previous step in your application. This configuration doesn't display additional input fields. If for some reason both `showEmail` and `email` are passed the `email` will have no effect over the displayed input field.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `string`                                                                                                                                                                                                                                                                                                                                                                                                     | `null`             | no       |
| `installments`\*         | The number of installments with which the transaction should be processed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | `number`<br />[1 .. 12]                                                                                                                                                                                                                                                                                                                                                                                      | `null`             | no       |
| `maxInstallments`\*      | The maximum amount of installments in the selector displayed by the widget.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | `number`<br />[1 .. 12]                                                                                                                                                                                                                                                                                                                                                                                      | `12`               | no       |
| `id`                     | `id` of the element that you wish to render the card widget in. _Example:_ `<div id="sumup-card"></div>`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `string`                                                                                                                                                                                                                                                                                                                                                                                                     | `"sumup-card"`     | no       |
| `donateSubmitButton`     | Changes the text of the submit button to "Donate".                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `boolean`                                                                                                                                                                                                                                                                                                                                                                                                    | `false`            | no       |
| `amount`                 | The `amount` you want to be displayed on the submit button. _Requires_ `currency` _and_ `locale` _to take effect._                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | `string`                                                                                                                                                                                                                                                                                                                                                                                                     | `null`             | no       |
| `currency`               | The `currency` for the `amount` you want to be displayed on the submit button.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | One of: `"EUR"`, `"BGN"`, `"BRL"`, `"CHF"`, `"CZK"`, `"DKK"`, `"GBP"`, `"HUF"`, `"NOK"`, `"PLN"`, `"SEK"`, `"USD"`                                                                                                                                                                                                                                                                                           | `null`             | no       |
| `locale`                 | Translates all texts into the given locale. Also specifies the formatting of the `amount` and `currency`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | One of:<br />`"bg-BG"`, `"cs-CZ"`, `"da-DK"`, `"de-AT"`, `"de-CH"`, `"de-DE"`, `"de-LU"`, `"el-CY"`, `"el-GR"`, `"en-GB"`, `"en-IE"`, `"en-MT"`, `"en-US"`, `"es-CL"`, `"es-ES"`, `"et-EE"`, `"fi-FI"`, `"fr-BE"`, `"fr-CH"`, `"fr-FR"`, `"fr-LU"`, `"hu-HU"`, `"it-CH"`, `"it-IT"`, `"lt-LT"`, `"lv-LV"`, `"nb-NO"`, `"nl-BE"`, `"nl-NL"`, `"pt-BR"`, `"pt-PT"`, `"pl-PL"`, `"sk-SK"`, `"sl-SI"`, `"sv-SE"` | `"en-GB"`          | no       |
| `country`                | Sets the country where the user account is from.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | One of: `"AT"`, `"BE"`, `"BG"`, `"BR"`, `"CH"`, `"CL"`, `"CO"`, `"CY"`, `"CZ"`, `"DE"`, `"DK"`, `"EE"`, `"ES"`, `"FI"`, `"FR"`, `"GB"`, `"GR"`, `"HR"`, `"HU"`, `"IE"`, `"IT"`, `"LT"`, `"LU"`, `"LV"`, `"MT"`, `"NL"`, `"NO"`, `"PL"`, `"PT"`, `"RO"`, `"SE"`, `"SI"`, `"SK"`, `"US"`                                                                                                                       | `null`             | no       |
| `googlePay`              | Required for accepting payments with the widget via Google Pay:<br/><ul><li>**`merchantId`** is a value provided by Google [after registration](https://developers.google.com/pay/api/web/guides/setup#registration). (not to be confused with your SumUp `merchantCode`)</li><li>**`merchantName`** is visible to the customer on the Google Pay payment flow.</li></ul>For more details check [Google Pay **`merchantInfo`** documentation](https://developers.google.com/pay/api/web/reference/request-objects#MerchantInfo).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | `{merchantId: string, merchantName: string}`                                                                                                                                                                                                                                                                                                                                                                 | `null`             | no       |

_\* Installments are available only to merchant users in Brazil._<br />
_\*\* ZIP code is required only for merchant users in the USA._

## Methods

| Name    | Description                               | Parameters                                           | Return Type                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ------- | ----------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mount` | Initializes and renders the payment form. | JSON object with a [configuration](#configurations). | Returns object that contains three methods: `submit`, `unmount` and `update`.<ul><li>`submit()` method will submit the form.</li><li>`unmount()` method will destroy the card.</li><li>`update({})` method will dynamically change some configurations, it accepts one argument which has to be an object with at least one of the following configuration keys: `checkoutId`, `email`, `amount`, `currency` or `installments`.</li></ul> |

## Alternative Payment Methods

Depending on the country a merchant is registered in, [Alternative Payment Methods (APMs)](/online-payments/apm) are available for accepting payments from your customers. Please note, the `show*` configuration properties from the [widget configurations](#configurations) do not apply to APMs. The APMs will only render fields applicable to the respective payment method.

You can begin offering APMs to your customers, once you are onboarded as a merchant. Request assistance with getting onboarded for APMs through our [contact form](/contact).

<Aside type="note">
  Installments are not applicable to Alternative Payment Methods.
</Aside>

## Custom Styling

Custom styling to most of the SumUp Payment Widget elements is enabled by the `data-sumup-id` attribute. To get all elements, query the DOM with `document.querySelectorAll('[data-sumup-id]')`.

Here's an example of updating styles for one of the elements:

```css
[data-sumup-id="widget__container"] {
  color: red;
  line-height: 18px;
}
```

You can also style child elements to those with the `data-sumup-id`, by chaining their tag or other uniquely identifiable attribute.

Elements like Payment Selector have some additional items you can query to extend your customizations. To style a specific Payment Selector, you need to appoint the `data-sumup-item=${payment.id}`.

```css
[data-sumup-id="payment_option"][data-sumup-item="blik"] {
  display: none;
}
```

## Using Your Own Submit Button

If you need to use your own submit button, you can achieve this by following the example below:

```html
<button id="custom-submit-button" class="custom-button">Pay your order</button>
<script type="text/javascript">
  document.addEventListener("load", function () {
    var sumupCard = SumUpCard.mount({
      checkoutId: "2ceffb63-cbbe-4227-87cf-0409dd191a98",
      onResponse: function (type, body) {
        console.log("Response from client", res);
        // Verify the checkout is processed correctly.
        // Display success message to the user and destroy the SumUpCard object:
        sumupCard.unmount();
      },
      showSubmitButton: false,
    });
  });
  document
    .getElementById("custom-submit-button")
    .addEventListener("click", function (event) {
      sumupCard.submit();
    });
</script>
```

## Handling Strict Content Security Policies

Pages with strict [Content Security Policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP) may experience issues with styles or images when rendering the SumUp Payment Widget. This section contains the necessary adjustments to render the Payment Widget properly.

To confirm your issue is related to CSP, check your browser's console for a similar error message:

```text
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' \*\*\* Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution.
```

### Required Configurations

In order to properly render the card widget with CSP in place, you must whitelist the following URLs for your application:

| Content Type | URL                                 |
| ------------ | ----------------------------------- |
| SDK & API    | 'https://\*.sumup.com'              |
| Images       | 'data:', 'https://static.sumup.com' |

Additionally, `nonce` is required to make inline styles work on your host page. For more information view [the CSP docs](https://content-security-policy.com/nonce/).

Example implementation with `nonce`:

```js
const express = require("express");
const app = express();
const http = require("http");
const server = http.createServer(app);

const port = process.env.PORT || 4000;

const crypto = require("crypto");

// Resources
const apisToConnect = ["https://gateway.sumup.com", "https://api.sumup.com"];

const imagesResources = [
  "data:", // inline icons
  "https://static.sumup.com",
  // For generated barcodes

  "https://api.sumup.com",
];

const scriptsResources = [
  "https://gateway.sumup.com",
  // PLUS nonce-$HASH
];

const stylesResources = [
  // nonce-$HASH
];

const framesResources = ["https://gateway.sumup.com"];

app.get("/", (req, res) => {
  const nonce = crypto.randomBytes(16).toString("base64");
  res.setHeader(
    "Content-Security-Policy",
    `default-src 'self';` +
      ` connect-src 'self' ${apisToConnect.join(" ")};` +
      ` img-src 'self' ${imagesResources.join(" ")};` +
      ` script-src 'self' ${scriptsResources.join(" ")} 'nonce-${nonce}';` +
      ` style-src 'self' 'nonce-${nonce}';` +
      ` frame-src 'self' ${framesResources.join(" ")};`,
  );

  // <script type="text/javascript" src="http://localhost:8003/sdkv2.js"></script>
  res.send(`
    <h1>Test CSP</h1>
    <div>Test using generated nonce: ${nonce}</div>
    <div id="sumup-card"></div>
    <script type="text/javascript" nonce="${nonce}">
      (window.SumUpPayment).mount({
        nonce: "${nonce}",
        checkoutId: '7538e178-c8c1-43a1-8eef-c29ab608edd1',
        onResponse: function(type, body) {
          console.log('Type', type);
          console.log('Body', body);
        }
      });
    </script>
    <a href="/without-nonce">See without nonce</a>
    <div>Footer</div>
 `);
});

server.listen(port, () => {
  console.log("listening on:", port);
});
```

If you continue to experience issues with rendering the Payment Widget, reach out to our support through this [contact form](/contact).