# Implement a Hosted Payment Page
source: https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-checkout/integrate-hosted-checkout/implementing-the-hosted-payment-page/index.md

You have two options for implementing the Hosted Payment Page:

* Embedded page is a component that is activated within your website's existing checkout page.
* Payment page is a separate page to which the payer is redirected from your existing checkout page.

Warning: If you have originally implemented a Lightbox page (with API v62 or earlier), your payment page is a modal dialog displayed on top of your existing checkout page. The Mastercard Gateway API versions do not directly support this implementation, but if you are migrating to Mastercard Gateway API version 100, you can use a Modal mode, which allows you to use the Lightbox as an extension of the Embedded page.

Once a checkout session has been established, the process of implementing the Hosted Payment Page for Hosted Checkout consists of the following steps:

1. Create a Checkout object.
2. Configure the Checkout object.
3. Use the appropriate method of the Checkout object to start the payment process.

In addition, you can define callbacks that are triggered when the payer takes certain actions during the payment process.  

The Hosted Payment Page implementation is done in your app or web site, using the [Checkout JavaScript (JS) library](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/index.md).

## Step 1: Create a checkout object {#step-1-create-a-checkout-object}

After the session has been initialized, you need to refer to the checkout.min.js file from the gateway server on your checkout page. This places a Checkout object into the Global scope.

```html
<script 
  src="{{host}}/static/checkout/checkout.min.js" 
  data-error="errorCallback" 
  data-cancel="cancelCallback">
</script>
```

## Step 2: Configure the checkout object {#step-2-configure-the-checkout-object}

Call the `Checkout.configure()` function and pass it a JSON object that includes the session.id returned from the [Initiate Checkout](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#hosted-checkout) operation earlier.

```js
Checkout.configure({
  session: {
    id: '<your_initiate_checkout_ID>'
  }
});
```

Alert:   

* In API v67 or later, the session object is the only field allowed through `configure()` - all other fields must be included through INITIATE CHECKOUT.
* Data passed in `Checkout.configure()` never overwrites the data you already provided in the INITIATE CHECKOUT operation.

## Step 3: Start the payment process on an Embedded page {#step-3-start-the-payment-process-on-an-embedded-page}

Start the payment process by calling the following method of the Checkout object.

* To display the checkout interaction on an Embedded page:

```js
Checkout.showEmbeddedPage('#embed-target')
```

## Step 3: Start the payment process on a Payment page {#step-3-start-the-payment-process-on-a-payment-page}

Start the payment process by calling the following method of the Checkout object.

* To display the checkout interaction on a Payment page:

```js
Checkout.showPaymentPage()
```

## HTML Code Example for Requesting an Embedded or Payment Page {#html-code-example-for-requesting-an-embedded-or-payment-page}

* Embedded
* Payment

```Embedded
<!DOCTYPE html>
<html>
  <head>
    <script 
      src="{{host}}/static/checkout/checkout.min.js" 
      data-error="errorCallback" 
      data-cancel="cancelCallback">
    </script>

    <script type="text/javascript">
      function errorCallback(error) {
        console.log(JSON.stringify(error));
      }

      function cancelCallback() {
        console.log('Payment cancelled');
      }

      Checkout.configure({
        session: {
          id: '<your_initiate_checkout_session_ID>'
        }
      });
    </script>
  </head>

  <body>
    <!-- Your content here -->
    <div id="embed-target"></div>

    <input 
      type="button" 
      value="Pay with Embedded Page" 
      onclick="Checkout.showEmbeddedPage('#embed-target');" 
    />
    <!-- Your content here -->
  </body>
</html>
```

```Payment
<!DOCTYPE html>
<html>
  <head>
    <script 
      src="{{host}}/static/checkout/checkout.min.js" 
      data-error="errorCallback" 
      data-cancel="cancelCallback">
    </script>

    <script type="text/javascript">
      function errorCallback(error) {
        console.log(JSON.stringify(error));
      }

      function cancelCallback() {
        console.log('Payment cancelled');
      }

      Checkout.configure({
        session: {
          id: '<your_initiate_checkout_session_ID>'
        }
      });
    </script>
  </head>

  <body>
    <!-- Your content here -->
    <div id="embed-target"></div>

    <input 
      type="button" 
      value="Pay with Payment Page" 
      onclick="Checkout.showPaymentPage();" 
    />
    <!-- Your content here -->
  </body>
</html>
```

## HTML Code Example the Modal Mode {#html-code-example-the-modal-mode}

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <link 
      rel="stylesheet" 
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" 
      integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" 
      crossorigin="anonymous" 
    />

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

    <button 
      type="button" 
      class="btn btn-primary" 
      data-toggle="modal" 
      data-target="#exampleModal"
    >
      Launch demo modal
    </button>

    <div 
      class="modal fade" 
      id="exampleModal" 
      tabindex="-1" 
      role="dialog" 
      aria-labelledby="exampleModalLabel" 
      aria-hidden="true"
    >
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button 
              type="button" 
              class="close" 
              data-dismiss="modal" 
              aria-label="Close"
            >
              <span aria-hidden="true">×</span>
            </button>
          </div>
          <div class="modal-body">
            <div id="hco-embedded"></div>
          </div>
          <div class="modal-footer">
            <button 
              type="button" 
              class="btn btn-secondary" 
              data-dismiss="modal"
            >
              Close
            </button>
            <button 
              type="button" 
              class="btn btn-primary"
            >
              Save changes
            </button>
          </div>
        </div>
      </div>
    </div>

    <script 
      src="https://code.jquery.com/jquery-3.6.0.slim.min.js" 
      integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" 
      crossorigin="anonymous"
    ></script>

    <script 
      src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/js/bootstrap.min.js" 
      crossorigin="anonymous"
    ></script>

    <script 
      src="{{host}}/static/checkout/checkout.min.js"
    ></script>

    <script>
      // Configure Checkout
      Checkout.configure({
        session: {
          id: "<your_initiate_checkout_ID>"
        }
      });

      // Show embedded page when modal is shown
      $('#exampleModal').on('shown.bs.modal', function () {
        Checkout.showEmbeddedPage('#hco-embedded', () => {
          $('#exampleModal').modal();
        });
      });

      // Clear sessionStorage when modal is hidden
      $('#exampleModal').on('hide.bs.modal', function () {
        sessionStorage.clear();
      });
    </script>
  </body>
</html>
```

## Step 4: Implementing callbacks {#step-4-implementing-callbacks}

Callbacks are provided to handle events that can occur during the payment interaction. Using callbacks is optional, but if you need them, you must define them in the body of the same tag that references `checkout.min.js`.

All defined callbacks must have an implementation. They are invoked when the relevant event is triggered. The following code sample shows an example of a callback (triggered if the payer cancels the payment) being defined and implemented on a page.

```html
<script 
  src="{{host}}/static/checkout/checkout.min.js"
  data-cancel="cancelCallback"
  data-beforeRedirect="Checkout.saveFormFields"
  data-afterRedirect="Checkout.restoreFormFields">
</script>

<script>
  function cancelCallback() {
    confirm('Are you sure you want to cancel?');
    // code to manage payer interaction
  }

  // Alternatively, you can redirect to a URL:
  // cancelCallback = "someURL";
</script>
```

There are two types of callback methods: basic callbacks and redirect callbacks.

### Basic callbacks {#basic-callbacks}

Basic callbacks are provided for the following events:

* **cancel** : When the payer cancels the payment interaction. Note: The cancel callback can only be used with a Payment Page, it does not work with an Embedded page.
* **error**: When an error is encountered.
* **complete**: When the payer completes the payment interaction.
* **timeout**: When the payer does not complete the payment within the time they are given to do it.

These callbacks can be defined as functions or as URLs. If you provide a URL instead of a function in a callback, the payer is redirected to this URL when the event is triggered.

### Redirect callbacks {#redirect-callbacks}

Since Hosted Checkout supports payment interactions that require the payer to be redirected away to other web sites to progress the payment, such as [PayPal](https://developer.mastercard.com/mastercard-gateway/documentation/payment-methods/digital-wallets/paypal/index.md), callbacks are provided to manage what happens before the redirect and after the return to Hosted Checkout to finalize transaction processing:

* `beforeRedirect`: Before the payer is presented with the payment interface. Returns data required to restore the payment interface state for use by `afterRedirect`.
* `afterRedirect`: When the payer returns from completing the payment interaction. Uses the data saved by `beforeRedirect` to return the saved payment interface state.

The Checkout object also provides two functions to help you implement the beforeRedirect and `afterRedirect` callbacks:

* `saveFormFields()`: Saves all current form fields for use by `restoreFormFields()`. Use in your beforeRedirect implementation or implement `beforeRedirect` as `Checkout.saveFormFields()`.
* `restoreFormFields()`: Restores form fields saved by `saveFormFields()`. Use in your `afterRedirect` implementation or implement `afterRedirect` as `Checkout.restoreFormFields()`.

## Frequently asked questions {#frequently-asked-questions}

Hosted Checkout can return a number of integration errors. See [Testing Steps](https://developer.mastercard.com/mastercard-gateway/documentation/test-cards/index.md) for more information about testing and errors. An error page displays when an incorrect Hosted Checkout request is attempted. Common causes for errors include:

* Missing mandatory fields.
* The web addresses (URLs) in the request do not include the full path.
If the payer double-clicks the Pay button, that is, submits the payment twice, then the transaction is not repeated with your or the payer's bank.
