# Make a Payment
source: https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/make-a-payment/index.md

This guide explains how to set up a payment system on your website using a session-based method. In this setup, you collect sensitive payment details like card numbers directly on your page using hosted fields---secure input fields provided by the payment gateway.
To do this, you use:

* The [Session JavaScript library](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/session/index.md) (session.js) to handle the secure parts in the browser.
* The [Mastercard Gateway API](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md) to manage the payment process on the server side. If you want to see a full example of how the entire payment page should look and work, check out the [Payment Page Code Example](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/make-a-payment/index.md#payment-page-code-example).

### Step 1: Create a session {#step-1-create-a-session}

Create a Session by submitting a [Create Session](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#session) request from your server. Specify a Session authentication limit of 25. The response returns a Session ID that you must use in the subsequent steps to reference this Session.

| HTTP Method |                              URL                               |
|-------------|----------------------------------------------------------------|
| POST        | {{host}}/api/rest/version/100/merchant/\<merchant_ID\>/session |

```json
{
  "session": {
    "authenticationLimit": 25
  }
}
```

### Step 2: Update the session with the order details {#step-2-update-the-session-with-the-order-details}

Update the Session with at least the currency and order amount by submitting an [Update Session](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#session) request from your server. The order currency is needed so that you can determine whether the credit card the payer wants to use is support and whether they need to provide their Card Security Code (CSC).

| HTTP Method |                                      URL                                      |
|-------------|-------------------------------------------------------------------------------|
| PUT         | {{host}}/api/rest/version/100/merchant/\<merchant_ID\>/session/\<session_ID\> |

```json
{
  "order": {
    "amount": 100,
    "currency": "USD"
  }
}
```

### Step 3: Include the session JavaScript library {#step-3-include-the-session-javascript-library}

To use the payment session on your website, you need to include a special JavaScript file called session.js, which is hosted by the payment gateway:

* Add a `<script>` tag inside the `<head>` section of your HTML page to load this file.
* The link to the file includes your **API version** and your **merchant ID**, so it is specific to your setup.
* Once added, this script creates a PaymentSession object that your page can use to handle the payment process.

```html
<html>
<head>  
<script src="{{host}}/form/version/100/merchant/<MERCHANTID>/session.js"></script>
</head>
</html>
```

### Step 4: Create the payment page {#step-4-create-the-payment-page}

Create the HTML code for your payment page, including the fields for gathering the necessary payment details from the payer.
Alert: To prevent submission of sensitive data to your server, ensure that all sensitive data fields are set as read-only and omit the name attribute.

You can use one or more of the following payment methods to capture payment details from the payer. The fields you need to include on your payment page depend on the payment method:

#### Credit and Debit cards {#credit-and-debit-cards}

You can capture the following card details in hosted fields:

* `card.number`
* `card.expiryMonth`
* `card.expiryYear`
* `card.securityCode`
* `card.nameOnCard`

Alert: All the fields are optional; however, if `card.expiryMonth` is used then `card.expiryYear` is mandatory and vice versa.

#### Gift cards {#gift-cards}

You can capture the following gift card details in hosted fields:

* `giftCard.number`
* `giftCard.pin`

For more information, see [Gift Cards](https://developer.mastercard.com/mastercard-gateway/documentation/payment-methods/alt-pay-methods/gift-cards/index.md).

#### Automated Clearing House (ACH) Payments {#automated-clearing-house-ach-payments}

You can capture payment details for Direct Payments (payments) and Direct Deposits (refunds) through the Automated Clearing House. You can capture the following Automated Clearing House details in hosted fields:

* `ach.routingNumber`
* `ach.bankAccountNumber`
* `ach.bankAccountNumberConfirmation`
* `ach.bankAccountHolder`
* `ach.accountType`

For more information, see the [Automated Clearing House](https://developer.mastercard.com/mastercard-gateway/documentation/payment-methods/alt-pay-methods/a2a/ach/index.md).

#### Click to Pay {#click-to-pay}

You can capture payment details from the Click to Pay interaction. For more information, see [Click to Pay Hosted Session](https://developer.mastercard.com/mastercard-gateway/documentation/gateway-features/click-to-pay/index.md) Integration.
Warning: For every supported payment method, the Hosted Session allows you to collect and submit full, partial, or individual (except card expiry month and card expiry year) payment details into a payment Session. You can use the returned payment Session in combination with [other payment data sources](https://developer.mastercard.com/mastercard-gateway/documentation/tutorials-and-guides/multiple-payment-sources/index.md) to process a payment. For example, if you have already tokenized the payer's card number and expiration date, you can use the Hosted Session to collect only the CSC or CVV, and use the card details from both sources collectively to perform a payment. Alternatively, if the card stored against a token has expired, you can use the Hosted Session to collect the new card expiration date in a payment Session and update the token.

The following sample code illustrates the necessary payment page fields for a credit card payment.

#### Example Request {#example-request}

```html
<!-- CREATE THE HTML FOR THE PAYMENT PAGE -->
    <div>
      Enter your payment details:
    </div>
    <div>
      Cardholder Name:
      <input type="text" id="cardholder-name" class="input-field" title="cardholder name"
      aria-label="enter name on card" value="" tabindex="1" readonly>
    </div>
    <div>
      Card Number:
      <input type="text" id="card-number" class="input-field" title="card number"
      aria-label="enter your card number" value="" tabindex="2" readonly>
    </div>
    <div>
      Expiry Month:
      <input type="text" id="expiry-month" class="input-field" title="expiry month"
      aria-label="two digit expiry month" value="" tabindex="3" readonly>
    </div>
    <div>
      Expiry Year:
      <input type="text" id="expiry-year" class="input-field" title="expiry year"
      aria-label="two digit expiry year" value="" tabindex="4" readonly>
    </div>
    <div>
      Security Code:
      <input type="text" id="security-code" class="input-field" title="security code"
      aria-label="three digit CCV security code" value="" tabindex="5" readonly>
    </div>
    <div>
      <button id="payButton" onclick="pay();">
        Pay Now
      </button>
    </div>
```

### Step 5: Configure the session {#step-5-configure-the-session}

Invoke the [PaymentSession.configure()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/session/index.md) function with a configuration object as an argument to attach the hosted fields to your payment page and configure the payment interaction. You need to provide the following in the configuration object:

* Session ID received when you created the Session.
* Field selectors for hosted fields for specific payment methods. The configuration replaces them with corresponding proxy fields embedded in iFrames hosted by the Mastercard Gateway. The proxy fields have the same look and feel as the replaced fields.
* Mitigation options for click jacking prevention. Click jacking, also known as a "UI redress attack", is when an attacker uses multiple transparent or opaque layers to trick a user into clicking on a button or link on another page when they were intending to click the top-level page. To use the Hosted Session, you must implement one or more of the following defenses against click jacking attacks and specify which defenses are implemented using the frameEmbeddingMitigation field:
  * Javascript: Include "frame-breaker" JavaScript on your payment page.
  * x-frame-options: Your server returns an X-Frame Options HTTP response header.
  * csp: Your server returns a Content-Security-Policy HTTP response header containing a frame-ancestors directive. For information on defending against click jacking attacks, see the [Click jacking Defense Cheat Sheet on the OWASP external website](https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html).
* [Callbacks](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/make-a-payment/index.md#payment-page-callbacks) for handling various events during the Hosted Session interaction:
  * `initialized()` is invoked when the hosted fields attach to your payment page.
  * `formSessionUpdate()` is invoked in response to the `PaymentSession.updateSessionFromForm(paymentType)` function (see next step).
* Interaction details that define the visibility and payer interaction options for some displayed information.

#### Session Configuration Example {#session-configuration-example}

```javascript
<body>
    PaymentSession.configure({
    session: "<your_session_ID>",
  fields: {
    // ATTACH HOSTED FIELDS TO YOUR PAYMENT PAGE FOR A CREDIT CARD
    card: {
      number: "#card - number",
      securityCode: "#security - code",
      expiryMonth: "#expiry - month",
      expiryYear: "#expiry - year",
      nameOnCard: "#cardholder - name"
    }
  },
  //SPECIFY YOUR MITIGATION OPTION HERE
  frameEmbeddingMitigation: ["javascript"],
  callbacks: {
    initialized: function(response) {
      // HANDLE INITIALIZATION RESPONSE
    },
    formSessionUpdate: function(response) {
      // HANDLE RESPONSE FOR UPDATE SESSION
    },
  },
  interaction: {
    displayControl: {
      formatCard: "EMBOSSED",
      invalidFieldCharacters: "REJECT"
    }
  }
});
</body>
```

### Step 6: Update the session with field details {#step-6-update-the-session-with-field-details}

After the payer has entered their payment details in the hosted fields, invoke the `PaymentSession.updateSessionFromForm()` function with the applicable payment method as an argument. The function stores the captured payment details into the payment Session. Once the operation completes, the `formSessionUpdate()` callback is invoked with a result parameter. Check the `result.status` field to determine if the operation was successful. For more information, see [Handling Callback Responses](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/make-a-payment/index.md#payment-page-callbacks).

#### Session update example {#session-update-example}

```javascript
function pay() {
  // Update the session with the input from hosted fields
  PaymentSession.updateSessionFromForm('card');
}
```

### Step 7: Create payment using the session {#step-7-create-payment-using-the-session}

Send the payment transaction (or other related operation) from your server to the gateway using the Session ID (session.id) in the request:

1. Send the [Retrieve Session](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/session/index.md) request to verify the details included in the Session.
2. Create the transaction request by adding any necessary fields not included in the Session. Warning: If you provide in the request a field that is already defined in the Session, the gateway uses the value in the request.
3. Send the transaction request. For more information about handling API requests, see [Making a Server API Request](https://developer.mastercard.com/mastercard-gateway/documentation/getting-started/make-server-api-req/index.md).

You can send multiple operations related to the payment using the same Session. For example, you can both initiate a payment with a [PAY](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#transaction) operation and store a token representing the payment details (for use in future transactions) with the [Create or Update Token](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#tokenization) operation.

### Payment page code example {#payment-page-code-example}

The following sample code illustrates the HTML code for a full payment page.

```html
<html>
<head>
    // INCLUDE SESSION.JS JAVASCRIPT LIBRARY 
    <script src="{{host}}/form/version/<version>/merchant/<merchant_ID>/session.js"></script>
    // APPLY CLICK-JACKING STYLING AND HIDE CONTENTS OF THE PAGE 
    <style id="antiClickjack">body{display:none !important;}</style>
</head>
              
<body>
    // CREATE THE HTML FOR THE PAYMENT PAGE
    <div>
      Enter your payment details:
    </div>
    <h3>
        Credit Card
    </h3>
    <div>
        Card Number:
        <input type="text" id="card-number" class="input-field" title="card number"
        aria-label="enter your card number" value="" tabindex="1" readonly>
    </div>
    <div>
        Expiry Month:
        <input type="text" id="expiry-month" class="input-field" title="expiry month"
        aria-label="two digit expiry month" value="" tabindex="2" readonly>
        </div>
    <div>
        Expiry Year:
        <input type="text" id="expiry-year" class="input-field" title="expiry year"
        aria-label="two digit expiry year" value="" tabindex="3" readonly>
    </div>
    <div>
        Security Code:
        <input type="text" id="security-code" class="input-field" title="security code"
        aria-label="three digit CCV security code" value="" tabindex="4" readonly>
    </div>
    <div>
        Cardholder Name:
        <input type="text" id="cardholder-name" class="input-field" title="cardholder name"
        aria-label="enter name on card" value="" tabindex="5" readonly>
    </div>
    <div>
        <button id="payButton" onclick="pay('card');">
          Pay Now
        </button>
    </div>            
    // JAVASCRIPT FRAME-BREAKER CODE TO PROVIDE PROTECTION AGAINST IFRAME
    CLICK-JACKING
    <script type="text/javascript">
        if (self === top) {
          var antiClickjack = document.getElementById("antiClickjack");
          antiClickjack.parentNode.removeChild(antiClickjack);
        } else {
          top.location = self.location;
        }
                  
        PaymentSession.configure({
          session: "<your_session_ID>",
          fields: {
           // ATTACH HOSTED FIELDS TO YOUR PAYMENT PAGE FOR A CREDIT CARD
           card: {
             number: "#card-number",
             securityCode: "#security-code",
             expiryMonth: "#expiry-month",
             expiryYear: "#expiry-year",
             nameOnCard: "#cardholder-name"
            }
        },
        //SPECIFY YOUR MITIGATION OPTION HERE
        frameEmbeddingMitigation: ["javascript"],
        callbacks: {
          initialized: function(response) {
            // HANDLE INITIALIZATION RESPONSE
          },
          formSessionUpdate: function(response) {
            // HANDLE RESPONSE FOR UPDATE SESSION
            if (response.status) {
              if ("ok" == response.status) {
                console.log("Session updated with data: " + response.session.id);
                //check if the security code was provided by the user
                if (response.sourceOfFunds.provided.card.securityCode) {
                  console.log("Security code was provided.");
                }
                //check if the user entered a Mastercard credit card
                if (response.sourceOfFunds.provided.card.scheme == 'MASTERCARD') {
                  console.log("The user entered a Mastercard credit card.")
                }
              } else if ("fields_in_error" == response.status) {
                console.log("Session update failed with field errors.");
                if (response.errors.cardNumber) {
                  console.log("Card number invalid or missing.");
                }
                if (response.errors.expiryYear) {
                  console.log("Expiry year invalid or missing.");
                }
                if (response.errors.expiryMonth) {
                  console.log("Expiry month invalid or missing.");
                }
                if (response.errors.securityCode) {
                  console.log("Security code invalid.");
                }
              } else if ("request_timeout" == response.status) {
                console.log("Session update failed with request timeout: " + response.errors.message);
              } else if ("system_error" == response.status) {
                console.log("Session update failed with system error: " + response.errors.message);
              }
            } else {
              console.log("Session update failed: " + response);
            }
          }
        },
        interaction: {
          displayControl: {
            formatCard: "EMBOSSED",
            invalidFieldCharacters: "REJECT"
          }
        }
      });
      function pay() {
        // UPDATE THE SESSION WITH THE INPUT FROM HOSTED FIELDS
        PaymentSession.updateSessionFromForm('card');
      }
    </script>
                  
</body>            
</html>
```

## Payment page callbacks {#payment-page-callbacks}

The Hosted Session allows you to use various callbacks to customize how the payment page behaves and what kind of feedback it provides to the payer.

### Callbacks for session configuration {#callbacks-for-session-configuration}

This section defines the Session configuration callbacks and the responses returned by their result callbacks. For an example of how to handle the callbacks in your payment page code, see [Payment Page Code Example](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/make-a-payment/index.md#payment-page-code-example).

The callbacks used in the [PaymentSession.configure()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/session/index.md) function:

* `initialized(result)` callback is invoked when the hosted fields are attached to the payment page:
  * If result.status=="ok", the hosted fields are successfully attached to your payment page.

### Successful Initialization response example {#successful-initialization-response-example}

```json
// An ok response
{
  "status": "ok"
}
```

* If result.status=="system_error" or result.status=="request_timeout", an error has occurred while attaching the hosted fields. Retry after a short delay.

### Failed Initialization response example {#failed-initialization-response-example}

```json
// An error response (system_error)
{
  "status": "system_error",
  "message": "System error message."
}
// An error response (request_timeout)
{
  "status": "request_timeout",
  "message": "Request timeout error message."
}
```

* `formSessionUpdate(result)` callback is invoked when the hosted field content is stored in the Session:
  * If result.status=="ok", the Session now contains the collected payment details.

### Form Session update example for successful response {#form-session-update-example-for-successful-response}

```json
// An ok response
{
  "status": "ok",
  "merchant": "TESTMERCHANT",
  "session": {
    "id": "SESSION000218450948092491657986""updateStatus": "SUCCESS",
    "version": "e3f144ce02"
  },
  "sourceOfFunds": {
    "provided": {
      "card": {
        "brand": "MASTERCARD",
        "expiry": {
          "month": "1",
          "year": "39"
        },
        "fundingMethod": "DEBIT",
        "nameOnCard": "John Smith",
        "number": "512345xxxxxx8769",
        "scheme": "MASTERCARD"
      }
    },
    "type": "CARD"
  },
  "version": "43"
}
```

* If result.status=="fields_in_error", the payer input is invalid. Prompt the payer to update their input. The errors response structure contains information about the invalid fields.

### Form Session update example for error response {#form-session-update-example-for-error-response}

```json
// An error response (fields_in_error)
{
  "status": "fields_in_error",
  "session": {
    "id": "SESSION000218450948092491657986"
  },
  "errors": {
    "cardNumber": "invalid",
    "securityCode": "invalid"
  },
  "version": "43"
}
```

* If result.status=="system_error" or result.status=="request_timeout", an error has occurred when processing the update. Retry the Session update after a short delay.

### Form Session update example for system error and timeout response {#form-session-update-example-for-system-error-and-timeout-response}

```json
// An error response (system_error)
{
    "status": "system_error",
    "session": {
        "id": "SESSION000218450948092491657986"
    },
    "errors": {
        "message": "System error message."
    },
    "version": "43"
}
  // An error response (request_timeout)
{
    "status": "request_timeout",
    "session": {
        "id": "SESSION000218450948092491657986"
    },
    "errors": {
        "message": "Request timeout error message."
    },
    "version": "43"
}
```

### Callbacks for hosted fields {#callbacks-for-hosted-fields}

The Hosted Session allows you to register callback functions to handle events that can occur on the hosted fields during the payer's interaction. The events allow you to track what the payer is doing and provide validation feedback to them during various payment interaction stages.

You can register callback functions for the following events:

* `onChange()`: Invoked when the input value in the hosted field in the iFrame has changed.
* `onFocus()`: Invoked when the hosted field in the iFrame has gained focus.
* `onBlur()`: Invoked when the hosted field in the iFrame has lost focus. Once the payer has finished typing and leaves the field, and this event is triggered, invoke the `validate()` function and display any errors for the field from the `validate()` function's callback.
* `onMouseOver()`: Invoked when a mouse over event occurs in the hosted field.
* `onMouseOut()`: Invoked when a mouse out event occurs in the hosted field.
* `onValidityChange()`: Invoked after the payer's each keystroke, providing feedback on the validity of the payer's data entry so far.

Warning: Regardless of how you handle the hosted field events above, you must expect and handle errors from the `formSessionUpdate()` session configuration callback. While the `validate()` function can indicate validity, the `formSessionUpdate()` validation is more comprehensive and can detect additional errors.

### Form Session update example for system error and timeout response {#form-session-update-example-for-system-error-and-timeout-response-1}

```JavaScript
PaymentSession.onBlur( ["card.number", "card.nameOnCard", "card.securityCode", "card.expiryYear", "card.expiryMonth"],

function(selector, role)

{
  PaymentSession.validate('card',
  function(allresult) {

    if (allresult.card[role].isValid) {

      console.log("The field is valid");
      document.querySelector(selector).style.borderColor = "green";

    } else {

      console.log("The field is invalid");

      document.querySelector(selector).style.borderColor = "red";

    }
  });
  PaymentSession.onFocus(['card.number', 'card.securityCode'],
  function(selector) {
    //handle focus event
  });
  PaymentSession.onChange(['card.securityCode'],
  function(selector) {
    //handle change event
  });
  PaymentSession.onMouseOver(['card.number'],
  function(selector) {
    //handle mouse over event
  });
  PaymentSession.onMouseOut(['card.number'],
  function(selector) {
    //handle mouse out event
  });

  PaymentSession.onValidityChange(["card.number", "card.nameOnCard"],
  function(selector, result) {

    if (result.isValid) {

      console.log("The field value is valid");

      document.querySelector(selector).style.borderColor = "green";

    } else if (result.isIncomplete) {
      console.log("The field value is not yet valid");
      document.querySelector(selector).style.borderColor = "grey";
    } else {

      console.log("The field value is invalid");

      document.querySelector(selector).style.borderColor = "red";

    }
  }
}
);
```

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

To handle this event, first use the [PAYMENT OPTIONS INQUIRY](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#gateway) operation to get a list of supported card types. Then inspect the card type information (`sourceOfFunds.provided.card.brand and sourceOfFunds.provided.card.scheme`) in the `PaymentSession.updateSessionFromForm('card')` response, validate it against the list of supported card types, and display an error message if the card type is not accepted. To find out whether CSC or CVV is required, use the [PAYMENT OPTIONS INQUIRY](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#gateway) operation. If the payer does not provide CSC/CVV, the `securityCode` field is NOT returned in the `PaymentSession.updateSessionFromForm('card')` response. If you require a CSC/CVV and no value is present, you need to display an error to the payer. There are known issues with event callbacks on the following operating systems and browsers:

* Internet Explorer 11 on Windows 10: If `interaction.displayControl.formatCard=EMBOSSED`, the `onChange()` event is not triggered when you change the value of a hosted field.
* iOS9 on iPhone 6+: The `onChange()` and `onBlur()` events are not triggered when the payer enters data in a hosted field and touches another field in the payment page. Further, the payer cannot navigate from hosted fields to other fields on the payment page or the reverse.

Alert: Hover events are not supported on touchscreen devices.
