# Click to Pay Hosted Session Integration
source: https://developer.mastercard.com/mastercard-gateway/documentation/gateway-features/click-to-pay/c2p-flows-for-hsi/index.md

Use the following steps to add Click to Pay (C2P) to your [Hosted Session integration](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/index.md) using the Click to Pay software development kit (SDK) and JavaScript (JS) library. You can find an HTML example of a basic integration at the end of this topic.

For more information on C2P, testing the completed integration, and some frequently asked questions, see [Click to Pay](https://developer.mastercard.com/mastercard-gateway/documentation/gateway-features/click-to-pay/index.md).

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

Create a session using the [CREATE SESSION](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#session) operation. The response returns a session ID that you must use in the subsequent steps to reference the session.

You can add or update fields in an existing session using the [UPDATE SESSION](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#session) operation. Include at least the following fields in a session:

* `session.id`  
  Identifier of the payment session.
* `order.amount`  
  Total amount of the order.
* `order.currency`  
  Currency of the order.

Warning: CREATE SESSION and UPDATE SESSION are server-side API Operations that are a prerequisite for integrating with the JS library. Only API version 62 or later supports Click to Pay. Integrate with API version 100 for full compatibility.

For request examples of the server-side API Operations, download the [Postman collection](https://www.postman.com/mastercard/mastercard-developers/collection/4fakvrd/mastercard-gateway-api).

## Step 2: Include the Click to Pay JavaScript API in your payment page {#step-2-include-the-click-to-pay-javascript-api-in-your-payment-page}

Add the Mastercard Gateway's [C2P JavaScript SDK](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) (click-to-pay.js) in your payment page by adding a script element to the head element in your HTML code. This places a ClickToPay object into the window namespace.

```html
<script type="text/javascript" src="{{host}}}}/click-to-pay/click-to-pay.min.js</script>
```

## Step 3: Configure the Click to Pay interaction {#step-3-configure-the-click-to-pay-interaction}

The configuration object allows you to configure the interaction between the payer and C2P on your payment page. When the payer is ready to pay for their order and you are loading your payment page, initiate the C2P interaction by invoking the [ClickToPay.configure()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function. For additional details and an example of the function, see the [ClickToPay.configure()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md).

The C2P library can take a few seconds to initialize. Initialize the components as early as possible during the page load so that the payer can quickly check out using C2P.

In the [ClickToPay.configure()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function, configure these details as defined in the later sections:

* parameters
* payment page components
* callbacks for the C2P interaction

##### Configuration Parameters {#configuration-parameters}

Use the parameters to define the details of your C2P interaction.

Table: Configuration Parameters
**Merchant parameters** **Session parameters** **Order parameters** **Interaction parameters** **Payer parameters** **Event parameters**

|                 Field                  |                    Required                    |        Type        |                                                                                                                                                                                                                                                                                                                                          Description                                                                                                                                                                                                                                                                                                                                           |
|----------------------------------------|------------------------------------------------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `merchant.id`                          | Yes                                            | String             | The gateway uses your merchant ID to determine your payment options.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `merchant.name`                        | Yes                                            | String             | Your trading name, for example, the name known to your payer.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `merchant.url`                         | Yes                                            | String             | The URL of your website that the payer is using.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `session.id`                           | Yes                                            | String             | Step 1 of the CREATE SESSION operation returns the Session ID.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `session.wsVersion`                    | Yes                                            | Integer            | Displays the API version used when submitting the CREATE SESSION operation in Step 1. The value must be \>= 62.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `session.paymentOptions`               | No                                             | Object             | Payment options inquiry response                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `order.amount`                         | Yes                                            | string             | Order amount. Use the value only for display, not for processing the payment.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `order.currency`                       | Yes                                            | string             | Order currency. The system uses this value for display only and not for processing the payment.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `interaction.billingPreference`        | No                                             | Enumeration string | This field indicates whether the C2P interaction collects the billing address. The possible values are: * NONE: the system does not collect the address. * FULL: the system collects full address. * POSTAL_COUNTRY: the system collects only the postcode/zip and country. If you do not provide the parameter, the system sets the default value to NONE.                                                                                                                                                                                                                                                                                                                                    |
| `interation.cardSelectionAction`       | No                                             | String             | Action for card selection with values such as SELECT_ONLY and SELECT_AND_PROCEED.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `interation.collectShippingAddress`    | No                                             | Boolean            | This field indicates whether the C2P interaction collects the billing address. The default value is false. By default, the payer can select any shipping address country. To restrict the list to countries that you ship goods to, configure your merchant profile for C2P in the Merchant Administration (MA) portal with allowed/excepted countries. If you have defined any restrictions, the payer can only select an allowed shipping address country. You cannot override the supported shipping address countries for a specific request, only for all requests within your merchant profile.                                                                                          |
| `interation.country`                   | No                                             | string             | Country-specific content, such as Terms and Conditions, presented to the payer during the C2P interaction. The value you have configured against your merchant profile in the gateway is used by default. If you want to override this value for this interaction, set this parameter to a valid ISO 3166 alpha-3 country value.                                                                                                                                                                                                                                                                                                                                                               |
| `interation.locale`                    | No                                             | String             | The language used during the C2P interaction. By default, the system uses the language configured in the payer's browser. If the system cannot determine the payer's language or does not support it, the system uses the `en_US` unless you provide a different value in this parameter.                                                                                                                                                                                                                                                                                                                                                                                                      |
| `interaction.cardSelectionAction`      | No                                             | String             | The system performs the action when the payer makes the card selection. The possible values are: * `SELECT_ONLY`: The UI displays a list of cards where each card entry is clickable. Selecting an entry automatically takes the payer to the next step. * `SELECT_AND_PROCEED`: The UI displays a list of cards using radio buttons. Selecting a radio button does not trigger any action. The payer needs to click **Continue** to continue to the next step. This is the default value.                                                                                                                                                                                                     |
| `interaction.showInlineCardListHeader` | No                                             | Boolean            | Indicates if the inline card list display includes a header with the Click to Pay logo and a list of logos for the supported card schemes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `interaction.suppressPayerInteraction` | No                                             | Boolean            | Allows you to suppress the Click to Pay interaction with the payer.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `interaction.skipDCFInteraction`       | No                                             | Boolean            | The payer must manually confirm their email address and phone number. This requirement applies only to Mastercard card enrollment. The `configure()` function requires the `customer.email` and `customer.mobilePhone` parameters for this feature to take effect. If set to true, the system does no prompt the payer with a **Confirm** message on the DCF (Digital Card Facilitator user interface) component and a brief loading screen displays. If not provided, the value defaults to false.                                                                                                                                                                                            |
| `payer.email`                          | Yes                                            | String             | Payer's email. C2P uses the value to look up the payer's profile within the SRC (Secure Remote Commerce) system. The system initiates the email lookup only if it does not recognize the device. If the system recognizes the device, it ignores this field. Inform payers on your site that the system uses their email for lookup, unless you have already told them that the system uses it to look up their C2P profile. You can include a notice informing that you partner with participating card schemes to deliver C2P for faster checkout and that the system securely shares the payer's email address with participating card schemes to check if they already have a C2P profile. |
| `payer.mobilePhone`                    | No                                             | Telephone number   | Payer's mobile phone or cell phone number in ITU-T E123 format, for example +1 607 1234 5678 The number consists of: * '+' * country code (1, 2 or 3 digits) * space * national number (which embeds single spaces characters for readability).                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `payer.firstName`                      | No                                             | String             | Payer's first name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `payer.lastName`                       | No                                             | String             | Payer's last name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `srcDCFCancel`                         | Yes (only if you intend to support Visa cards) | -                  | Visa's current design for C2P closes its C2P session if the payer selects the "X" displayed in the top-right corner of the Visa DCF component. When the system sends this event, reinitialize C2P as recommended (call the configure() function) to ensure open sessions for all card schemes.                                                                                                                                                                                                                                                                                                                                                                                                 |

##### Payment Page Components {#payment-page-components}

C2P provides several components that you can embed on your payment page to enhance the C2P interaction. Create div elements at the location in your payment page where you want these components to appear and identify the div elements within the elements section of the configuration object.

Table: Available payment page components

|   Field    | Required |                                                          Description                                                           |
|------------|----------|--------------------------------------------------------------------------------------------------------------------------------|
| `cardList` | Yes      | The Card List component displays the DOM element ID.                                                                           |
| `otp`      | No       | The One-Time Password (OTP) component displays the DOM element ID. If not provided, the system displays the OTP as an overlay. |
| `dcf`      | Yes      | The DCF component displays the DOM element ID. If not provided, the system displays the DCF component as an overlay.           |

##### Callbacks {#callbacks}

Define the actions that the system invokes during the C2P interaction as callbacks.

### onStateChange Callback {#onstatechange-callback}

The system determines the initial flow when you call the configure() function:

* If the system detects a valid C2P cookie, it uses the 'Returning user with cookie' flow and displays the card list component.
* If the system detects a valid C2P email, it uses the 'Returning user with email' flow, prompts the payer for the OTP, and then displays the card component.
* If the system does not detect a valid cookie or email, it uses the 'New User' flow.

The [onStateChange](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) callback is triggered when the C2P interaction state changes. You can use it to determine which components are visible and in what stage the payer is within the flow.

### onStateChange Callback Object Example {#onstatechange-callback-object-example}

```json
{
  "oldState": {
    "payerState": {
      "deviceRecognized": true,
      "email": "payer@test.com"
    },
    "elementState": {
      "cardList": {
        "selector": "cardListContainer",
        "visible": true
      },
      "otp": {
        "selector": "otpContainer",
        "visible": false
      },
      "dcf": {
        "selector": "dcfContainer",
        "visible": false
      }
    }
  },
  "newState": {
    "payerState": {
      "deviceRecognized": true,
      "email": "payer@test.com"
    },
    "elementState": {
      "cardList": {
        "selector": "cardListContainer",
        "visible": false
      },
      "otp": {
        "selector": "otpContainer",
        "visible": false
      },
      "dcf": {
        "selector": "dcfContainer",
        "visible": true
      }
    }
  },
  "diffState": {
    "elementState": {
      "dcf": {
        "selector": "dcfContainer",
        "visible": true
      }
    }
  }
}
```

The following table provides examples of how to manage the state changes with the different flows.

### States changes {#states-changes}

|                                    State                                    |                                                                                                                           Old State field value                                                                                                                            |                                                                                                                            New State field value                                                                                                                            |                                   Comments                                    |
|-----------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|
| After the payer clicks the card and before the system redirects them to DCF | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: true}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ```  | -                                                                             |
| After checkout is complete                                                  | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ``` | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | onComplete callback returns correlationId, scheme, digitalCardId. Goto step 6 |

### Returning user with cookie flow {#returning-user-with-cookie-flow}

|                                    State                                    |                                                                                                                           Old State field value                                                                                                                            |                                                                                                                            New State field value                                                                                                                            |                                              Comments                                              |
|-----------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
| After the payer clicks the card and before the system redirects them to DCF | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: true}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ```  | -                                                                                                  |
| After checkout is complete                                                  | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ``` | ``` { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | onComplete callback returns the correlation ID, scheme, and digital card ID. Continue from step 6. |

### Returning user with email flow {#returning-user-with-email-flow}

|                                    State                                    |                                                                                                                             Old State field value                                                                                                                              |                                                                                                                             New State field value                                                                                                                              |                                              Comments                                              |
|-----------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
| After a valid OTP is entered                                                | ``` { payerState:  { email: 'payer@test.com', emailEnrolled: true, emailVerified: false }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: true}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | ``` { payerState:  { email: 'payer@test.com', emailEnrolled: true, emailVerified: true }, elementState: { cardList: {selector: '#cardListContainer', visible: true}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ```  | -                                                                                                  |
| After the payer clicks the card and before the system redirects them to DCF | ``` { payerState:  { email: 'payer@test.com', emailEnrolled: true, emailVerified: true }, elementState: { cardList: {selector: '#cardListContainer', visible: true}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ```  | ``` { payerState:  { email: 'payer@test.com', emailEnrolled: true, emailVerified: true }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ```  | -                                                                                                  |
| After checkout is complete                                                  | ``` { payerState:  { email: 'payer@test.com', emailEnrolled: true, emailVerified: true }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ```  | ``` { payerState:  { email: 'payer@test.com', emailEnrolled: true, emailVerified: true }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | onComplete callback returns the correlation ID, scheme, and digital card ID. Continue from step 6. |

### New user flow {#new-user-flow}

<br />

|                                      State                                      |                                                                                                                                           Old State field value                                                                                                                                           |                                                                                                                                           New State field value                                                                                                                                            |                                                                                                              Comments                                                                                                               |
|---------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Page load with email                                                            | ``` { } ```                                                                                                                                                                                                                                                                                               | ``` { payerState:  { deviceRecognized: false, email: ‘payer@test.com’, emailEnrolled: false, emailVerified: false }, elementState: { cardList: {selector: ‘#cardListContainer’, visible: false}, otp: {selector:’#otpContainer’, visible: false}, dcf: {selector:’#dcfContainer’, visible: false} } } ```  | Since the system does not recognize the payer's C2P profile, you can display card input fields, gather the details from the payer, and update the session. The email is blank, if not provided within the configuration parameters. |
| Call the `checkoutWithNewCard()` function before the DCF component is displayed | ``` { payerState:  { deviceRecognized: false, email: 'payer@test.com', emailEnrolled: false, emailVerified: false }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | ``` { payerState:  { deviceRecognized: false, email: 'payer@test.com', emailEnrolled: false, emailVerified: false }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ```   | -                                                                                                                                                                                                                                   |
| After checkout is complete                                                      | ``` { payerState:  { deviceRecognized: false, email: 'payer@test.com', emailEnrollled: false, emailVerified: false }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: true} } } ``` | ``` { payerState:  { deviceRecognized: false, email: 'payer@test.com', emailEnrollled: false, emailVerified: false }, elementState: { cardList: {selector: '#cardListContainer', visible: false}, otp: {selector:'#otpContainer', visible: false}, dcf: {selector:'#dcfContainer', visible: false} } } ``` | onComplete callback returns the correlation ID, scheme, and digital card ID. Continue from step 6.                                                                                                                                  |

### onComplete Callback {#oncomplete-callback}

The system triggers the [onComplete callback](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) when the payer has completed the interaction with the DCF component.

This function uses two arguments:

* scheme: Card scheme
* correlationId: Unique identifier for the C2P interaction (for this scheme)

Use these details in step 6 to retrieve the payment details for this C2P interaction.

### onError Callback {#onerror-callback}

The [onError callback](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) returns an error object, if an error occurs during the C2P interaction. It contains two fields:

```json
{
  "errorCode": "INVALID_INPUT",
  "errorMessage": "session id is required"
}
```

**Integration Error Codes**

|         Error Code         |                   Error Message                   |                                           Your Action                                            |
|----------------------------|---------------------------------------------------|--------------------------------------------------------------------------------------------------|
| CALLBACKS_ONCOMPLETE_ERROR | Missing Argument: onComplete callback is required | Include the onComplete callback function in the configure() function.                            |
| CALLBACKS_ONERROR_ERROR    | Missing Argument: onError callback is required    | Include the onError callback method in the configure() function.                                 |
| MERCHANT_ID_ERROR          | Missing Argument: Merchant ID is required         | Include the merchant.id field in the configure() function.                                       |
| MERCHANT_NAME_ERROR        | Missing Argument: Merchant Name is required       | Include the merchant.name field in the configure() function.                                     |
| MERCHANT_URL_ERROR         | Missing Argument: Merchant URL is required        | Include the merchant.url field in the configure() function.                                      |
| SESSION_ID_ERROR           | Missing Argument: Session ID is required          | Include the session.id field in the configure() function.                                        |
| MISSING_API_VERSION_ERROR  | Missing Argument: API Version is required         | Include the wsVersion field in the configure() function.                                         |
| ORDER_AMOUNT_ERROR         | Missing Argument: Order Amount is required        | Include the order.amount field in the configure() function.                                      |
| ORDER_CURRENCY_ERROR       | Missing Argument: Order currency is required      | Include the order.currency field in the configure() function.                                    |
| MIN_API_VERSION_ERROR      | API version should be greater than or equal to 62 | Change the wsVersion field value to at least 62, all Operations must be made using 62 or higher. |
| CARD_LIST_ERROR            | Missing Argument: Elements.cardList is required   | Include the elements.cardList field that links to the card list component div.                   |
| DCF_ERROR                  | Missing Argument: Elements.dcf is required        | Include the elements.dcf field that links to the card list component div.                        |
| MISSING_EMAIL_ERROR        | Missing Argument: Email is required               | Include the customer.email field in the configure() function.                                    |
| CUSTOMER_EMAIL_ERROR       | Customer email format error                       | Ensure your site accepts only valid payer email addresses.                                       |
| INTERACTION_LOCALE_ERROR   | Interaction locale format error                   | Provide a valid locale using the format _, such as en_US.                                        |
| INTERACTION_COUNTRY_ERROR  | Interaction country format error                  | Provide a valid ISO 3166 alpha-3 Country value in the interaction.country field.                 |

Table: Checkout error codes

|         Error Code         |                             Error Message                             |                                                        Needed Action                                                         |
|----------------------------|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| CARD_MISSING               | The digital card ID or encrypted card object is required but missing. | C2P is unavailable, revert to the guest checkout flow.                                                                       |
| CARD_ADD_FAILED            | Unable to add card when combined flow executed                        | C2P is unavailable, revert to the guest checkout flow.                                                                       |
| CARD_SECURITY_CODE_MISSING | The combined flow requires you to supply card security.               | Ensure the cardSecurityCode field in the ClickToPay.checkoutWithNewCard() function contains a 3-digit value (or 4 for Amex). |
| CARD_INVALID               | Invalid card number when combined flow executed.                      | Ensure the primaryAccountNumber field in the ClickToPay.checkoutWithNewCard() function is a valid card.                      |
| CARD_NOT_RECOGNIZED        | The system cannot recognize the specified card.                       | Ensure the primaryAccountNumber field in the ClickToPay.checkoutWithNewCard() function is a valid card.                      |
| CARD_EXP_INVALID           | Invalid card expiration date.                                         | Ensure the panExpirationYear and panExpirationMonth fields in the ClickToPay.checkoutWithNewCard() function are valid.       |
| MERCHANT_DATA_INVALID      | Merchant data is invalid                                              | C2P is unavailable, revert to the guest checkout flow.                                                                       |
| UNABLE_TO_CONNECT          | Unable to connect to / Launch DCF.                                    | C2P is unavailable, revert to the guest checkout flow.                                                                       |
| AUTH_INVALID               | Invalid federated ID token.                                           | C2P is unavailable, revert to the guest checkout flow.                                                                       |

Standard C2P Error Codes

|            Error Code             |                                                                                                                                         Error Message                                                                                                                                          |                                                                          Needed Action                                                                           |
|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| REQUEST_TIMEOUT                   | The request took longer than the permitted time to complete. The service is experiencing a high volume of calls. Try again later. It could also be because the SDK is unable to communicate with its iframe.                                                                                   | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| SERVER_ERROR                      | This indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.                                                                                                                                                                              | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| INVALID_PARAMETER                 | At least one request parameter contains an invalid value. This error also occurs when a required field is missing. Note: Whenever possible, provide client-side validation to avoid an unnecessary round trip to the server. The API specification includes the simple validation constraints. | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| INVALID_REQUEST                   | The server could not understand the request, typically because a data field is not in a particular format. For example, base64 decoding has failed. The message field provides additional clarification of what part or field of the request is incorrect.                                     | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| AUTH_ERROR                        | The server does understand the request but cannot authenticate.                                                                                                                                                                                                                                | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| NOT_FOUND                         | The requested resource/business entity does not exist. The system may hide the resource for security reasons.                                                                                                                                                                                  | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| TERMS_AND_CONDITIONS_NOT_ACCEPTED | Terms and Conditions not accepted.                                                                                                                                                                                                                                                             | Revert to the guest checkout flow.                                                                                                                               |
| IS_CONFIGURED_ERROR               | configure() did not complete. Initialize the configuration first.                                                                                                                                                                                                                              | Ensure your integration called the configure() function. Ensure you allow sufficient time for the function to complete before making the C2P components visible. |
| SRCI_ID_MISSING                   | The identifier for the SRC Initiator is missing.                                                                                                                                                                                                                                               | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| DPA_ID_MISSING                    | The identifier for the Digital Payment Identifier (DPA) is missing                                                                                                                                                                                                                             | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| SRCI_TXID_MISSING                 | The SRC Initiator transaction identifier is missing.                                                                                                                                                                                                                                           | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| DPA_TXOPT_MISSING                 | The DPA Transaction Options structure is missing.                                                                                                                                                                                                                                              | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |
| INVALID_STATE                     | The account exists but is not in an "active" status for this program.                                                                                                                                                                                                                          | Revert to the guest checkout flow.                                                                                                                               |
| CONSUMER_ID_MISSING               | The consumer identity was not required but supplied.                                                                                                                                                                                                                                           | Revert to the guest checkout flow.                                                                                                                               |
| FRAUD                             | The user account was locked or disabled.                                                                                                                                                                                                                                                       | Revert to the guest checkout flow.                                                                                                                               |
| ID_FORMAT_UNSUPPORTED             | Invalid session ID                                                                                                                                                                                                                                                                             | C2P is unavailable, revert to the guest checkout flow.                                                                                                           |

### Delay of OTP for returning users recognized by email (optional) {#delay-of-otp-for-returning-users-recognized-by-email-optional}

If C2P recognizes the payer based on their email, it automatically displays the OTP provided by C2P.

If, for any reason, you want to initiate the C2P interaction but suppress the OTP provided by C2P until a later time (while you display additional screens to the payer before they proceed), add the `interaction.suppressPayerInteraction` field in the [ClickToPay.configure()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function.

If you set the `interaction.suppressPayerInteraction` field to true, the configure() function sets up the C2P interaction and checks if the system recognizes the payer using their email or a cookie or is a new user. However, the function does not trigger the C2P interaction with the payer (display any related components).

If the field is omitted or set to false, the configure() function sets up the C2P interaction, determines whether the payer is recognized using their email or a cookie or is a new user, and immediately triggers the C2P interaction with the payer.

If the `interaction.suppressPayerInteraction` field is set to true, you must take the following actions based on the payer's recognition status. If the payer is:

* **Recognized based on their email** (`emailEnrolled` = true and `emailVerified` = false), the merchant app can apply additional steps within their flow prior to initiating C2P's OTP check. Afterwards, you must call the [ClickToPay.initiatePayerInteraction()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function to display the OTP to the payer.
* **Not recognized based on their email** (they are either a new user or recognized from a cookie), the merchant app must call the `initiatePayerInteraction()` function immediately.

## Step 4: Update email address changes {#step-4-update-email-address-changes}

If the payer can change their email address on the same page that shows the C2P components, push any changes to the payer email address to the C2P SDK. Every time the payer updates their email address, call the ClickToPay.lookupCustomer(email) function to update the C2P SDK. The payer email is used to look up whether this payer has an existing C2P profile associated with their email address.

If you collect the email address from the payer on your site, inform the payer that their email is used to look up their C2P profile. You can include a tooltip next to the email input box informing the payer that 'you partner with the participating card schemes to deliver C2P for faster checkout and that email is securely shared with participating card schemes to check if the payer already has a C2P profile.'

If the updated email address is:

* Linked to an existing C2P profile:
  * The system triggers the onStateChange callback with `newState.payerState.emailEnrolled` = true.
  * The C2P JavaScript SDK displays the OTP input form.
* Not linked to an existing C2P profile, the system triggers the onStateChange callback with the `newState.payerState.emailEnrolled` = false.

## Step 5: Implement checkout {#step-5-implement-checkout}

If the payer decides to checkout using an existing card from their C2P profile, call the [ClickToPay.checkoutWithExistingCard()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function after the payer selects the card from the card list. The function takes the payer to the card confirmation screen in the DCF component.

If the payer decides to enroll a new card into their C2P profile or does not have a profile:

1. Display the card input form as Hosted Session fields so that the payer can enter their payment details and click **Pay**. Display the fields for the following:

   * Card number
   * Security code
   * Expiry month and year
   * Name on the card
2. Retrieve the card scheme from the Hosted Session using the [PaymentSession.onCardTypeChange](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/session/index.md) callback, the system triggers the callback when the payer fills in the card number in the hosted field.

3. Call the [ClickToPay.isEnrollmentAvailableForScheme()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function using the scheme.
   The function checks the supplied scheme against `paymentTypes.card.walletProviders[n].secureRemoteCommerce.scheme[n].name` in the [PAYMENT OPTIONS INQUIRY](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#gateway) operation response to determine the scheme has enabled you.
   If the function returns false, exit this flow, and use the guest checkout flow to process the card normally without C2P.

4. Display and gather consent:

   * If you are in the US, include information that if the payer chooses to continue, you will share the payer's card details, billing address, and email with participating card schemes to allow enrolling the payer in C2P for faster checkouts.
   * If you are located outside the US, display:
     * Unticked consent box.
     * Consent text where the payer agrees to share card details, billing address, and email with participating card schemes to allow enrolling the payer in C2P for faster checkouts.
5. When the payer clicks the **Pay** button on your payment page to progress to the next stage:

   * If you are located outside the US and the consent box is not ticked, the payer has not consented to share data with C2P. Follow the guest checkout flow and process the card normally without C2P.
   * If you are in the US or outside the US and the user has ticked the consent box, update the session using the [PaymentSession.updateSessionFromForm()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/session/index.md) function. You can also update the session with an optional billing address using the billing object in an [UPDATE SESSION](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#session) request. If you insert the payer billing details into the payment session, the payer does not need to retype them again during C2P enrollment.
6. After updating the session, call the [ClickToPay.checkoutWithNewCard()](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/js-libraries/click-to-pay/index.md) function, which takes the payer to the card enrollment screen in the DCF component:

   * If the function fails, the system invokes the onError callback. Take the necessary steps to resolve the error.
   * If the function succeeds, the system redirects the payer to the DCF component.
7. The payer interacts with the DCF component to ease enrollment. After the system calls the onComplete callback, the C2P interaction is complete, and you can continue to step 6 to update the session with C2P details.

## Step 6: Update Session with Click to Pay payment details {#step-6-update-session-with-click-to-pay-payment-details}

Request the gateway to retrieve the payment details for the C2P interaction and store them in the session, after your payer has successfully completed the C2P interaction.

Submit a server-side [UPDATE SESSION FROM WALLET](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#wallet) API request with:

* Session ID in the request URL.
* Correlation ID and scheme as returned in the onComplete callback.

### UPDATE SESSION FROM WALLET Request Example {#update-session-from-wallet-request-example}

| HTTP Method |                               URL                                |
|-------------|------------------------------------------------------------------|
| POST        | https://{{host}}/merchant/\<merchant_ID\>/session/\<session_ID\> |

```json
{
  "apiOperation": "UPDATE_SESSION_FROM_WALLET",
  "order": {
    "walletProvider": "SECURE_REMOTE_COMMERCE"
  },
  "wallet": {
    "secureRemoteCommerce": {
      "srcCorrelationId": "<correlationId_provided_in_payloadCallback>",
      "scheme": "<scheme_provided_in_payloadCallback>"
    }
  }
}
```

If the Click to Pay interaction successfully updates the session with the payment details, display a payment confirmation screen to confirm that all details are correct before the payer commits to the payment. If the session update fails, ask your payer to select another checkout option.

## Step 7: Perform EMV 3-D Secure authentication (optional) {#step-7-perform-emv-3-d-secure-authentication-optional}

If you want to authenticate the payer, perform [EMV 3-D Secure authentication](https://developer.mastercard.com/mastercard-gateway/documentation/security-and-fraud/authentication/3d-secure-auth/index.md) using the session. For detailed instructions, see [EMV 3-D Secure with the EMV 3-D Secure JavaScript API](https://developer.mastercard.com/mastercard-gateway/documentation/security-and-fraud/authentication/3d-secure-auth/3ds-js-api/index.md).

## Step 8: Perform the payment operation {#step-8-perform-the-payment-operation}

Alert: Due to a limitation with Visa's DCF functionality, if the payer chooses to return to the original card entry or selection page to use a different card for payment after they have completed the DCF portion of the flow, you need to reinitialize the SDK. The recommended approach is to call the configure() function again.

After the payer commits to the payment (and the EMV 3-D Secure Authentication succeeds, if performed), use the session to submit the payment for processing from your server. For example, you can submit an [AUTHORIZE](https://developer.mastercard.com/mastercard-gateway/documentation/api-reference/v100/rest/api-ops/index.md#transaction) request.

The system uses the payment details stored in the session from the C2P interaction to process the payment. You can use the same session for a number of API Operations. For more information on making payment requests within a session, see [Payment Sessions](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/create-payment-session/index.md).

For guest checkout flows, use the basic [Hosted Session implementation](https://developer.mastercard.com/mastercard-gateway/documentation/integrations-types/hosted-session/integrate-hosted-session/index.md) to gather the card details from hosted fields and add them to the session before sending the payment operation.

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

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

```json
{
  "apiOperation": "AUTHORIZE",
  "session": {
    "id": "<session_ID>"
  }
}
```

### HTML example for the integration {#html-example-for-the-integration}

This section describes a simple integration for the Hosted Session to collect payer's credit card details and configure C2P.

#### Hosted Session Integration Example {#hosted-session-integration-example}

```html
<html>
  <head>
    <!-- INCLUDE SESSION.JS JAVASCRIPT LIBRARY -->
    https://{{host}}/form/version/<Version>/merchant/<Merchant ID>/session.js</script>

    <!-- INCLUDE CLICK-TO-PAY.MIN.JS JAVASCRIPT LIBRARY -->
    <host name>/static/click-to-pay/click-to-pay.min.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>

    <!-- CREATE THE HTML FOR THE CLICK-TO-PAY INTERACTION -->
    <div>C2P Fields Below------</div>
    Email: <input id="payerEmail" onblur="updateEmail();" /><br/>
    <div id="cardListContainer"></div><br/>
    <div id="otpContainer"></div><br/>
    <div id="cardFacilitator"></div><br/>
    <div id="coid"></div><br/>

    <!-- 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: {
          card: {
            number: "#card-number",
            securityCode: "#security-code",
            expiryMonth: "#expiry-month",
            expiryYear: "#expiry-year",
            nameOnCard: "#cardholder-name"
          }
        },
        frameEmbeddingMitigation: ["javascript"],
        callbacks: {
          initialized: function(response) {
            console.log('initialized: ' + response);
            if (response.status === 'ok') {
              configure();
            }
          },
          formSessionUpdate: function(response) {
            if (response.status) {
              if (response.status === "ok") {
                console.log("Session updated with data: " + response.session.id);
                if (response.sourceOfFunds.provided.card.securityCode) {
                  console.log("Security code was provided.");
                }
                if (response.sourceOfFunds.provided.card.scheme === 'MASTERCARD') {
                  console.log("The user entered a Mastercard credit card.");
                }
                ClickToPay.isEnrollmentAvailableForScheme(response.sourceOfFunds.provided.card.scheme, function(canEnroll) {
                  console.log('Card can be enrolled', canEnroll);
                  if (canEnroll) {
                    ClickToPay.checkoutWithNewCard();
                  }
                });
              } else if (response.status === "fields_in_error") {
                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 (response.status === "request_timeout") {
                console.log("Session update failed with request timeout: " + response.errors.message);
              } else if (response.status === "system_error") {
                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() {
        PaymentSession.updateSessionFromForm('card');
      }
    </script>

    <script type="text/javascript">
      var payloadCallback = function(correlationId, scheme) {
        console.log('Payload callback complete with correlation id %s and scheme %s', correlationId, scheme);
      };

      var errorCallback = function(error) {
        console.log('Error callback triggered with error ' + error);
        console.log(error);
      };

      var cancelCallback = function() {
        console.log('Cancel callback triggered');
      };

      function configure() {
        ClickToPay.configure({
          merchant: {
            id: "<your_gateway_merchant_ID>",
            name: "<your_gateway_name>",
            url: "<your_web_site_URL>"
          },
          session: {
            id: "<your_session_ID>",
            wsVersion: <api_version>
          },
          order: {
            amount: <amount>,
            currency: "<currency>"
          },
          interaction: {
            billingPreference: "FULL",
            collectShippingAddress: true,
            locale: "<locale>",
            country: "<country code>"
          },
          customer: {
            email: "<payers_email_address>"
          },
          elements: {
            cardList: "cardListContainer",
            otp: "otpContainer",
            dcf: "cardFacilitator"
          },
          callbacks: {
            onComplete: function(correlationId, scheme) {
              console.log("onComplete fired");
              console.log("Correlation ID: " + correlationId);
              console.log("Scheme: " + scheme);
              document.getElementById("coid").innerHTML = 'Correlation ID: ' + correlationId + ', Scheme: ' + scheme;
            },
            onStateChange: function(changeInfo) {
              console.log("onStateChange fired");
              console.log(changeInfo);
            },
            onError: function(errInfo) {
              console.log("onError fired");
              console.log(errInfo);
            }
          }
        });
      }

      function updateEmail() {
        ClickToPay.lookupCustomer(document.getElementById("payerEmail").value);
      }
    </script>
  </body>
</html>
```

