# Authenticating with PAAY 3DS on Landers

* [Enabling the PAAY Plugin](#enabling-the-paay-plugin)
* [Finding Your PAAY API Key](#finding-your-paay-api-key)
* [Direct API](#direct-api)
  * [Rebills](#rebills)
  * [Authenticating Upsells](#authenticating-upsells)
  * [3DS 2.1](#id-3ds-2.0)
* [Testing](#testing)
* [Suggested PAAY Practices](#suggested-paay-practices)

***

### Enabling the PAAY Plugin <a href="#enabling-the-paay-plugin" id="enabling-the-paay-plugin"></a>

Follow the steps in the [PAAY Plugin](/crm/plugins/authentication/paay.md) article to enable the PAAY plugin.

### Finding Your PAAY API Key <a href="#finding-your-paay-api-key" id="finding-your-paay-api-key"></a>

Once you have added the PAAY plugin, you can find your **paayApiKey** to use with the PAAY JavaScript you put on your lander by clicking on the PAAY tile (**Admin → Plugins → Authentication**).

<figure><img src="/files/HfKJYuiz6N2kke0WON0x" alt=""><figcaption></figcaption></figure>

You can also hit the Edit icon and copy the paayApiKey from the edit form.

<figure><img src="/files/i9iNF9Rlo2Ws8XBa97iG" alt=""><figcaption></figcaption></figure>

### Direct API <a href="#direct-api" id="direct-api"></a>

1\) Go to your checkout page code and make sure that the card inputs are inside of a form with an id attribute.

`<form id="kform">`

2\) Add the following data-threeds attributes to your card inputs:

| **card input name** | **data-threeds attribute** |
| ------------------- | -------------------------- |
| cardNumber          | pan                        |
| cardMonth           | month                      |
| cardYear            | year                       |

Code example:

`<input name='cardNumber' type='TEXT' maxlength=16 isRequired data-threeds="pan"> <select name='cardMonth' style='width:30%' isRequired data-threeds="month"> <select name='cardYear' style='width:30%' isRequired data-threeds="year">`

3\) Add the hidden inputs **x\_transaction\_id** and **paayAmount** inside of the same form as the card inputs. Initialize the x\_transaction\_id input value to “1234” since a Javascript function will be added in a later step to randomly generate that value. Set the paayAmount input value to the total amount of the transaction if it is static or to an empty string if it is calculated upon selection or submission.

`<input type="hidden" name="x_transaction_id" value="1234" data-threeds="id"/> <input type='hidden' name='paayAmount' id='paayAmount' value='' data-threeds="amount">`

4\) Add these scripts to your page before the closing body tag:

`<script src="https://cdn.3dsintegrator.com/threeds.min.latest.js"></script> <script type="application/javascript"> var id = document.querySelector('[data-threeds=id]'); var uniqueId = function() { return 'id-' + Math.random().toString(36).substr(2, 16); }; id.value = uniqueId(); </script> <script> var tds = new ThreeDS("kform", "paayApiKeyGoesHere", null, {autoSubmit:false, endpoint:"https://sandbox-api.3dsintegrator.com", verbose:true}); </script> </body>`

The first parameter of ThreeDS is the form id (The example from step 1 was \<form id=”kform”>).

The second parameter of ThreeDS is your paayApiKey which can be found following the steps in the Finding Your PAAY API Key section above.

The fourth parameter of ThreeDS is the options object.

* autoSubmit
  * true: Authentication will be automatically attempted as soon as the customer has filled in the required card inputs.
    * Default if autoSubmit not included in options object.
    * pros: May speed up the order processing time for the customer since authentication is started before submission and less code to integrate.
    * cons: Less control over when authentication happens, authentication may not be completed before submission / Import Order is called.
  * false: You will need to add code that calls the ThreeDS verify function.
    * pros: More control over how authentication is called (for example: you won’t want try to authenticate every card since it only works with Mastercard and Visa and can code to not authenticate in those circumstances), you can code to make sure authentication is completed and 3DS values sent in Import Order
    * cons: May add time to order processing as perceived by customer
  * We suggest setting autoSubmit to **false** and will provide instructions on calling the verify function in the next steps.
* endpoint
  * testing: "<https://sandbox-api.3dsintegrator.com>"
  * production: remove endpoint property from options object
* verbose
  * true: You can inspect element in the browser and see verbose output in the console
* rebill
  * decimal total amount of rebill cycle 2 transaction to also authenticate the cycle 2 rebill transaction
  * If authentication is successful, these rebill 3DS parameters will be automatically added to the form as the inputs **rebill\_cavv**, **rebill\_xid**, and **rebill\_eci**, and the CRM will send them to the gateway with the **cycle 2 rebill transaction** at the time of rebilling.

5\) Add the following code if implementing the autoSubmit = false option. Otherwise skip to step 6.

5a) Code to check the card number and only attempt authentication if Mastercard or Visa based on first character of cardNumber input value (3=Amex, 6=Discover):

`const cardNumber = document.getElementsByName("cardNumber")[0] ? document.getElementsByName("cardNumber")[0].value : null; if(cardNumber) { const firstCCDigit = cardNumber.charAt(0); if(firstCCDigit !== "3" && firstCCDigit !== "6") { triggerPAAY(); //Run PAAY authentication } }`

5b) Code to trigger the PAAY authentication:

`function triggerPAAY() { const paayCallback = function(data) { <import Order> } const successCallbackFunction = paayCallback; //if you don't want to accept orders without successful 3DS authentication, //make this a separate function that returns decline message to customer const failureCallbackFunction = paayCallback; tds.verify(successCallbackFunction, failureCallbackFunction, {amount: initialAmount}); if(tds.errors.length > 0) { const paayError = tds.errors[0]; } }`

6\) If authentication is successful, the PAAY JavaScript will automatically add the 3DS values as the hidden inputs **cavv**, **xid**, and **eci** inside your form.

7\) After getting the 3DS parameters from PAAY through the JavaScript on your lander, you will send them as the **cavv**, **xid**, **eci**, **rebill\_cavv**, **rebill\_xid**, **rebill\_eci** parameters in [Import Order](https://apidocs.checkoutchamp.com/#275a54c6-b4b0-414c-819b-7387e9a81f58) API calls to Checkout Champ.

More information can be found at: <https://docs.3dsintegrator.com/docs/javascript-sdk>

#### Rebills <a href="#rebills" id="rebills"></a>

To also authenticate the cycle 2 rebill transaction and send the 3DS parameters to the gateway upon the first (cycle 2) rebilling, either set the rebill property of the options object while initializing ThreeDS or set tds.options.rebill before calling tds.verify.

This value is the decimal formatted total amount of the cycle 2 rebill transaction.

If authentication is successful, rebill 3DS parameters will be automatically added to the form as the inputs **rebill\_cavv**, **rebill\_xid**, and **rebill\_eci**, and the CRM will send them to the gateway with the **cycle 2 rebill transaction** at the time of rebilling.

Initializing ThreeDS with rebill option example:

`<script> var tds = new ThreeDS("kform", "paayApiKeyGoesHere", null, {autoSubmit:false, endpoint:"https://sandbox-api.3dsintegrator.com", verbose:true, rebill:89.95}); </script> </body>`

Setting rebill property after initializing the ThreeDS object tds variable example:

`tds.options.rebill = 89.95;`

#### Authenticating Upsells <a href="#authenticating-upsells" id="authenticating-upsells"></a>

In order to authenticate the upsell transaction, you will need to save the cardNumber, cardMonth, and cardYear to session storage and then add hidden inputs with the data-threeds attributes pan, month, and year to your upsell page form. Then follow the same steps as for the checkout page and send the cavv, eci, xid, rebill\_cavv, rebill\_eci, rebill\_xid on your Import Upsale call.

#### 3DS 2.1 <a href="#id-3ds-2.0" id="id-3ds-2.0"></a>

Replace this script:

`<script src="https://cdn.3dsintegrator.com/threeds.min.latest.js"></script> //JavaScript library for 3DS 1.2`

with the script for 3DS 2.0:

`<script src="https://cdn.3dsintegrator.com/threeds.2.min.latest.js"></script> //JavaScript library for 3DS 2.1`

PAAY will return additional parameters for 3DS 2.1 that you will need to send in the Import Order API and the Import Upsale API as the **cavv**, **xid**, and **eci** parameters.

| **3DS 2.1 parameter returned by PAAY** | **Parameter to send to Import Order / Import Upsale API** |
| -------------------------------------- | --------------------------------------------------------- |
| authenticationValue                    | cavv                                                      |
| dsTransId                              | xid                                                       |
| eci                                    | eci                                                       |
| acsTransId                             | acsTransId                                                |
| status                                 | threeDsStatus                                             |

&#x20;

***

### Testing <a href="#testing" id="testing"></a>

You can run a test using cardNumber 4111111111111111, cardMonth 01, cardYear 21.

During testing you can see the verbose messaging in the console.

You can see the parameters after they have been created by the JavaScript by inspecting the form.

If you are testing with NMI, you may see the decline message "XID data must be 20 bytes" when you submit the order. That message means that your test 3DS parameters were successfully sent to NMI.\ <br>

\
If the 3DS parameters are passed in properly on the Import call and the transaction goes to a gateway that accepts 3rd Party 3DS you will see a tag that says \*3DSecure underneath the result of the transaction.

&#x20;

<figure><img src="/files/YzYKTabpWTr8sihVsK4a" alt=""><figcaption></figcaption></figure>

***

### Suggested PAAY Practices <a href="#suggested-paay-practices" id="suggested-paay-practices"></a>

**Rebills**

We recommend authenticating the cycle 2 transaction rebill amount in addition to authenticating your cycle 1 transaction.

&#x20;

**Trial Authentications**

For trials, we recommend following these practices:

* **Hold Trial Charge** - Authenticate the cycle 2 transaction amount and send as the initial authentication amount. Do not attempt a PAAY rebill authentication.
* **Full Authorize & Void** and **Validate Card** Trials or any trial with either no cycle 1 price or only shipping for cycle 1 - Run the PAAY authentication using the cycle 2 transaction amount and then send to Checkout Champ as rebill 3DS parameters.

&#x20;

**FAQ**

Q) How come I cannot see the returned 3ds values from PAAY’s API?

A) Please check the PAAY SDK and confirm that the 'addResultToForm' sdk option is set to True. This sdk option is embedded as a default config and set to true with the integration. Any changes made to this can lead to unexpected results on your page.\ <br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.checkoutchamp.com/crm/plugins/authentication/paay/authenticating-with-paay-3ds-on-landers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
