Click to Pay Hosted Session Integration
Use the following steps to add Click to Pay (C2P) to your Hosted Session integration using the Click to Pay SDK and JavaScript (JS) API. 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.
Step 1: Create and update a session
Create a session using the CREATE 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 operation. At least the following fields are required in a session:
session.id
Identifier of the payment session.order.amount
Total amount of the order.order.currency
Currency of the order.
For request examples of the server-side API operations, download the Postman collection.
Step 2: Include the Click to Pay JavaScript API in your payment page
Include the C2P JavaScript SDK (click-to-pay.js
) provided by the Mastercard Gateway in your payment page by adding a script element within the head element in your HTML code. This places a ClickToPay object into the window namespace.
<script type="text/javascript" src="https://test-nbkpayment.mtf.gateway.mastercard.com/form/static/click-to-pay/click-to-pay.min.js"></script>
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()
function. For additional details and an example of the function, see the API Reference.
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()
function, configure the parameters, payment page components, and callbacks for the C2P interaction, as defined in the following sections.
Configuration Parameters
Use the parameters to define the details of your C2P interaction.
Table: Configuration Parameters
Field | Required | Type | Description |
---|---|---|---|
merchant.id |
Yes | string | Your merchant ID, used by the gateway to determine your payment options. |
merchant.name |
Yes | string | Your trading name, for example, the name known to your payer. |
merchant.url |
Required | URL string | URL of your website that the payer is using. |
session.id |
Yes | string | Session ID returned from the CREATE SESSION operation in Step 1. |
session.wsVersion |
Yes | int | WS API version used when submitting the CREATE SESSION operation in Step 1. The value must be >= 62. |
order.amount |
Yes | string | Order amount. The value is used for display only and not for processing the payment. |
order.currency |
Yes | string | Order currency. The value is used for display only and not for processing the payment. |
interaction.billingPreference |
No | enumeration string | Whether a billing address is collected during the C2P interaction. The possible values are:
|
interation.collectShippingAddress |
No | boolean | Whether a shipping address is collected during the C2P interaction. 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, you must configure your merchant profile for C2P via the Merchant Administration (MA) with either a list of allowed countries or a list of 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.locale |
No | string | Language used during the C2P interaction. By default, the language configured in the payer's browser is used. If the payer's language cannot be determined or is not supported, en_US is used unless you provide a different value in this parameter.
|
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. |
interaction.cardSelectionAction |
No | string | Action to be performed when the payer makes the card selection. The possible values are:
|
interaction.skipDCFInteraction |
No | Boolean | Whether the payer must manually confirm their email address and phone number. This only applies to Mastercard card enrollment at this time. The customer.email and customer.mobilePhone parameters are required within the configure() function for this feature to take effect.If set to true, the payer is not prompted with a Confirm message on the DCF (Digital Card Facilitator user interface) component and a brief loading screen appears. If not provided, the value defaults to false. |
customer.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 email lookup is initiated only if the device is not recognized. If the device is recognized, this field is ignored. Include information on your site that the payer's email is used for the lookup purpose, unless you already informed the payer that their email address is used for looking 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 payer's email address is securely shared with participating card schemes to check if they already have a C2P profile. |
customer.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:
|
customer.firstName |
No | String | Payer's first name. |
customer.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 this event is sent, it is recommended that you reinitialize C2P (call the configure() function) to ensure open sessions for all card schemes. |
Payment Page Components
C2P provides several components that can be embedded 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 be displayed and identify the div elements within the elements section of the configuration object.
Table: Available Payment Page Components
Field | Required | Description |
---|---|---|
cardList |
Yes | DOM element ID where the Card List component is displayed. |
otp |
No | DOM element ID where the One Time Password (OTP) component is displayed. If not provided, the OTP is displayed as an overlay. |
dcf |
Yes | DOM element ID where the DCF component is displayed. If not provided, the DCF component is displayed as an overlay. |
Callbacks
You must define the actions to be invoked during the C2P interaction as callbacks.
onStateChange Callback
The initial flow is determined after you call the configure()
function:
- If a valid C2P cookie is detected, the 'Returning user with cookie' flow is used and the card list component is displayed.
- If a valid C2P email is detected, the 'Returning user with email' flow is used and the payer is prompted for an OTP before the card list component is displayed.
- If no valid cookie or email is detected, the 'New User' flow is used.
The onStateChange
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.
oldState : { payerState: { deviceRecognized: true, email: 'payer@test.com', //masked email if not supplied in customer.email }, elementState: { cardList: {selector: 'cardListContainer', visible: true}, otp: {selector:'otpContainer', visible: false}, dcf: {selector:'dcfContainer', visible: false} } }, newState: { 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} } }, diffState: { elementState: { dcf: {selector:'dcfContainer', visible: true} } }
The following table provides examples of how to manage the state changes with the different flows.
Table: States changes
State | Old State field value | New State field value | Comments |
---|---|---|---|
Page load (before cardlist is displayed) after isRecognized and before cardList is displayed | {} | { 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} } } |
- |
after card is clicked and before redirecting 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
State | Old State field value | New State field value | Comments |
---|---|---|---|
Page load after isRecognized() and before the card list is displayed |
{} | { 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} } } |
- |
After a card is clicked and before redirecting to the DCF component | { 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. |
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 a card is clicked before redirecting to the DCF component | { 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. |
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 payer's C2P profile is not recognized, 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
The onComplete callback is triggered 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)
These details must be used in step 6 to retrieve the payment details for this C2P interaction.
onError Callback
The onError callback returns an error object if an error occurs during the C2P interaction. It contains two fields:
{ errorCode: 'INVALID_INPUT', errorMessage: 'session id is required' }
Table: 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 customer.email field in the configure() function. |
CUSTOMER_EMAIL_ERROR |
Customer email format error | Ensure only valid payer email addresses are accepted by your site. |
INTERACTION_LOCALE_ERROR |
Interaction locale format error | Provide a valid locale using the format <language>_<country>, 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 was required but is 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 |
Card security must be supplied when combined flow executed. | Ensure the cardSecurityCode field in the ClickToPay.checkoutWithNewCard() function contains a 3-digit value (or 4 digits 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 specified card was not recognized. | Ensure the primaryAccountNumber field in the ClickToPay.checkoutWithNewCard() function is a valid card. |
CARD_EXP_INVALID |
Invalid card expiry 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. This could mean the service is experiencing a high volume of calls. You should try again later. It may 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 |
The value provided for one or more request parameters is considered invalid. This error is also generated when a required field is missing. Note: Whenever possible you should provide client-side validation to avoid an unnecessary round trip to the server. Simple validation constraints are documented as part of the API specification. | C2P is unavailable, revert to the guest checkout flow. |
INVALID_REQUEST |
The server could not understand the request. Usually this means a data field must be in a particular format but is not. For example, base64 decoding may have failed. The message field may provide additional clarification of what part/field of the request is considered 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 resource might also be hidden 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. Configuration should be initialized 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 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 required but not 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)
If the payer is recognized by C2P based on their email, the default behavior is to automatically show 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()
function.
If you set the interaction.suppressPayerInteraction
field to true, the configure() function sets up the C2P interaction and checks whether the payer is recognized 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, checks whether the payer is recognized using their email or a cookie or is a new user, as well as 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
andemailVerified = false
), the merchant app can apply additional steps within their flow prior to initiating C2P's OTP check. Afterwards, you must call theClickToPay.initiatePayerInteraction()
function to display the OTP to the payer. - Not recognized based on their email (they are a new user or are recognized from a cookie), the merchant app must call the
initiatePayerInteraction()
function immediately.
Step 4: Update email address changes
If the payer can change their email address on the same page that shows the C2P components, any changes to the payer email address need to be pushed 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
onStateChange
callback is triggered withnewState.payerState.emailEnrolled = true
. - The OTP input form is displayed by the C2P JavaScript SDK.
- The
- Not linked to an existing C2P profile, the
onStateChange
callback is triggered with thenewState.payerState.emailEnrolled = false
.
Step 5: Implement checkout
If the payer decides to checkout using an existing card from their C2P profile, call the ClickToPay.checkoutWithExistingCard()
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:
- Display the card input form as Hosted Session fields so that the payer can enter their payment details and click Pay. You must display the fields for the following:
- Card number
- Security code
- Expiry month and year
- Name on the card
- Retrieve the card scheme from the Hosted Session using the
PaymentSession.onCardTypeChange
callback, which is triggered when the payer fills in the card number in the hosted field. - Call the
ClickToPay.isEnrollmentAvailableForScheme()
function using the scheme.
The function checks the supplied scheme againstpaymentTypes.card.walletProviders[n].secureRemoteCommerce.scheme[n].name
in the PAYMENT OPTIONS INQUIRY operation response to determine whether you are enabled for the scheme.
If the function returnsfalse
, exit this flow, and use the guest checkout flow to process the card normally without C2P. - Display and gather consent:
- If you are located 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.
- 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 sharing data with C2P. Follow the guest checkout flow and process the card normally without C2P.
- If you are located in the US or outside the US and the user has ticked the consent box, update the session using the
PaymentSession.updateSessionFromForm()
function.
You can also update the session with an optionalbilling
address using the billing object in an UPDATE 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.
- After updating the session, call the
ClickToPay.checkoutWithNewCard()
function, which takes the payer to the card enrollment screen in the DCF component:
- If the function fails, the
onError
callback is called. Take the necessary steps to resolve the error. - If the function succeeds, the payer is redirected to the DCF component.
- If the function fails, the
- The payer interacts with the DCF component to facilitate enrollment. Once the
onComplete
callback is called, 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
You must 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 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 |
---|
URL: "https://test-nbkpayment.mtf.gateway.mastercard.com/form/version/<version>/merchant/<merchant_ID>/session/<session_ID> HTTP Method POST { "apiOperation":"UPDATE_SESSION_FROM_WALLET", "order":{ "walletProvider":"SECURE_REMOTE_COMMERCE" }, "wallet":{ "secureRemoteCommerce":{ "srcCorrelationId":"<correlationId_provided_in_payloadCallback>, "scheme":"<scheme_provided_in_payloadCallback>" } } } |
If the session is successfully updated with the payment details from the C2P interaction, display a payment confirmation screen to confirm that all details are correct before the payer commits to the payment. If the session has not been successfully updated, ask your payer to select another checkout option.
Step 7: Perform 3D Secure authentication (optional)
If you want to authenticate the payer, perform 3D Secure Authentication using the session. For detailed instructions, see 3DS with the 3DS JavaScript API.
Step 8: Perform the payment operation
After the payer commits to the payment (and the 3D Secure Authentication succeeds, if performed), use the session to submit the payment for processing from your server. For example, you can submit an AUTHORIZE request.
The payment details stored in the session from the C2P interaction are used 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.
For guest checkout flows, use the basic Hosted Session implementation to gather the card details from hosted fields and add them to the session before sending the payment operation.
AUTHORIZE Request Example |
---|
URL: "https://test-nbkpayment.mtf.gateway.mastercard.com/form/version/{version}//merchant/<merchant_ID>/order/<order_ID>/transaction/<transaction_ID> HTTP Method PUT { "apiOperation":"AUTHORIZE", "session": { "id": "<session_ID>" } } |
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 SessionIntegration Example
<html> <head> <!-- INCLUDE SESSION.JS JAVASCRIPT LIBRARY --> <script src="https://test-nbkpayment.mtf.gateway.mastercard.com/form/version/<Version>/merchant/<Merchant ID>/session.js"></script> <!-- INCLUDE CLICK-TO-PAY.MIN.JS JAVASCRIPT LIBRARY --> <script type="text/javascript" src="<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>Please 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: { // 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) { console.log('initialized: ' + response) if(response.status === 'ok') { //configure C2P configure() } }, 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 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.") } ClickToPay.isEnrollmentAvailableForScheme(response.sourceOfFunds.provided.card.scheme, function (canEnroll) { console.log('Card can be enrolled', canEnroll) if(canEnroll) { ClickToPay.checkoutWithNewCard(); } }); } 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> <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: { //BILLING PREFERENCE WITH ONE OF THE FOLLOWING VALUES: NONE, FULL, POSTAL_COUNTRY billingPreference: "FULL", collectShippingAddress: true, locale: "<locale>", country: "<country code>" }, customer: { email: "<payers_email_address>"//OPTIONAL }, elements: { cardList: "cardListContainer", otp: "otpContainer", // OPTIONAL 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>