Client-Side Encryption

Client-Side Encryption (CSE) is Adyen's programming technique to encrypt sensitive cardholder data on the client side and securely transfer this data to the payment gateway to process a payment.

Integration types

Adyen offers you three integration types to choose from:

Adyen hosts the encryption library with your public key injected into JavaScript code. You retrieve this library from the unique URL provided to you by Adyen, and thus you don't need to download and host the adyen.encrypt.min.js on your servers.

Sign in to the  Customer Area using your company-level account.
  1. Go to Settings > Users and filter the list of users by System in the drop-down box.
  2. Navigate to the Web Service (ws) user page.
  3. Go to  Library location.
    If the library is not available yet, click Generate and then Save to create a new URL.

Form template

Build your payment form using this template and add a way to reference to this form from JavaScript. For example, define a unique  id attribute value for this form by adding  id="adyen-encrypted-form".

<form method="POST" action="#handler" id="adyen-encrypted-form">
    <input type="text" size="20" autocomplete="off" data-encrypted-name="number" />
    <input type="text" size="20" autocomplete="off" data-encrypted-name="holderName" />
    <input type="text" size="2" maxlength="2" autocomplete="off" data-encrypted-name="expiryMonth" />
    <input type="text" size="4" maxlength="4" autocomplete="off" data-encrypted-name="expiryYear" />
    <input type="text" size="4" maxlength="4" autocomplete="off" data-encrypted-name="cvc" />
    <input type="hidden" value="generate-this-server-side" data-encrypted-name="generationtime" />
    <input type="submit" value="Pay" />
</form>

Also, do the following:

  • For the form.action attribute, replace #handler to the payment handler URL on your server.
  • Card input fields should not have a name attribute, but are annotated by the data-encrypted-name attribute, to mark them for encryption.

    Replacing name with data-encrypted-name restricts raw card data from being posted to your servers and avoids impact transaction security and violate PCI regulations.

  • Add a hidden  generationtime field to include a server-side timestamp in the data you submit with the form. It determines whether a payment request is valid or not: transactions submitted later than 24 hours from the timestamp value are refused.

    • Format: ISO 8601;  YYYY-MM-DDThh:mm:ss.sssTZD
    • Example: 2017-07-17T13:42:40.428+01:00

    The generation time value must be created server-side, because the client browser system clock may not be correctly synchronized, which would cause the payment transaction to fail.

JavaScript

Plain JavaScript

<script type="text/javascript" src="https://test.adyen.com/hpp/cse/js/{your Test WS user's library token}.shtml"></script>
<!-- For live: 
   <script type="text/javascript" src="https://live.adyen.com/hpp/cse/js/{your Live WS user's library token}.shtml"></script>
   Note that this token is not your public key, but a library token instead.
-->

Initialize the easy encryption form as in the HTML Form based integration. The AMD style is not yet available for this library.

// The form element to encrypt.
var form    = document.getElementById('adyen-encrypted-form');

// Form and encryption options. See adyen.encrypt.simple.html for details.
var options = {};

// Create the form.
// Note that the method is on the adyen object, not the adyen.encrypt object.
adyen.createEncryptedForm(form, options); 
</script>

Prevent payment form reload

If you have implemented a single-page interface and do not want the form to reload the page when the payment gets submitted, implement the onsubmit option.

After including the JavaScript cryptographic library, you can use JavaScript or AJAX to customize the POST submission behaviour.

For example, you can:

  • Pass an additional options parameter in the createEncryptedForm method.
  • Change the name of the encrypted data container. Its default name is adyen-encrypted-data.
  • Submit the form using AJAX instead of the default submit action, as shown in this example:
var encryptedBlobFieldName = "myFieldName";

options.name = encryptedBlobFieldName;
options.onsubmit = function(e) {
    var encryptedData = form.elements[encryptedBlobFieldName].value;
    // ... Your AJAX code here ....
    e.preventDefault();
};

adyen.createEncryptedForm(form, options);

This integration binds to existing HTML in the page, adding a hidden input containing the encrypted card data to the form at the moment the form is submitted. The complete integration requires HTML markup to be present in the page, as well as accompanying JavaScript to enable the behavior.

  1. Download adyen.encrypt.min.js and host it yourself. This supports both HTML-based and JavaScript-only integrations.
  2. Download adyen.encrypt.nodom.min.js and host it yourself. Only supports JavaScript-only integration.

Form template

Build your payment form using this template and add a way to reference to this form from JavaScript. For example, define a unique  id attribute value for this form by adding  id="adyen-encrypted-form".

<form method="POST" action="#handler" id="adyen-encrypted-form">
    <input type="text" size="20" autocomplete="off" data-encrypted-name="number" />
    <input type="text" size="20" autocomplete="off" data-encrypted-name="holderName" />
    <input type="text" size="2" maxlength="2" autocomplete="off" data-encrypted-name="expiryMonth" />
    <input type="text" size="4" maxlength="4" autocomplete="off" data-encrypted-name="expiryYear" />
    <input type="text" size="4" maxlength="4" autocomplete="off" data-encrypted-name="cvc" />
    <input type="hidden" value="generate-this-server-side" data-encrypted-name="generationtime" />
    <input type="submit" value="Pay" />
</form>

Also, do the following:

  • For the form.action attribute, replace #handler to the payment handler URL on your server.
  • Card input fields should not have a name attribute, but are annotated by the data-encrypted-name attribute, to mark them for encryption.

    Replacing name with data-encrypted-name restricts raw card data from being posted to your servers and avoids impact transaction security and violate PCI regulations.

  • Add a hidden  generationtime field to include a server-side timestamp in the data you submit with the form. It determines whether a payment request is valid or not: transactions submitted later than 24 hours from the timestamp value are refused.

    • Format: ISO 8601;  YYYY-MM-DDThh:mm:ss.sssTZD
    • Example: 2017-07-17T13:42:40.428+01:00

    The generation time value must be created server-side, because the client browser system clock may not be correctly synchronized, which would cause the payment transaction to fail.

JavaScript

In addition to the above the HTML template, there are two variants to including the library. The original plain JavaScript variant relies on a global adyen.encrypt object, while on popular demand an AMD style module has been added.

Plain JavaScript

Include the Adyen encryption library to your page.

<script type="text/javascript" src="js/adyen.encrypt.min.js"></script>

Enrich a form in your page with the library on submit and (optionally) validation behaviors.

// The form element to encrypt.
var form    = document.getElementById('adyen-encrypted-form');
 
// The public key.
var key     =   "your key as retrieved from the Customer Area Web Service user page";

// Form and encryption options. See adyen.encrypt.simple.html for details.
var options = {};

// Bind encryption to the form.
adyen.encrypt.createEncryptedForm(form, key, options);

Require.js

Make sure you include require.js or an alternative AMD module loader in your page.

<script src="path/to/libs/require.js/2.1.17/require.min.js"></script>

You can either rename the adyen.encrypt.min.js to adyen/encrypt.js, or add a paths configuration:

// Your paths config, or rename the adyen.encrypt.min.js to adyen/encrypt.js require.config({ paths: { 'adyen/encrypt' :
'../simple/js/adyen.encrypt.min' } });

In the main.js or a similar file, enrich the form using a require call.

require(['adyen/encrypt'], function(adyenEncrypt) {
    // The form element to encrypt.
    var form    = document.getElementById('adyen-encrypted-form');
 
    // The public key.
    var key     =   "your key as retrieved from the Customer Area Web Service user page";
 
    // Form and encryption options. See adyen.encrypt.simple.html for details
    var options = {};
 
    // Bind encryption to the form.
    adyenEncrypt.createEncryptedForm(form, key, options);
});
</script>

Prevent payment form reload

If you have implemented a single-page interface and do not want the form to reload the page when the payment gets submitted, implement the onsubmit option.

After including the JavaScript cryptographic library, you can use JavaScript or AJAX to customize the POST submission behaviour.

For example, you can:

  • Pass an additional options parameter in the createEncryptedForm method.
  • Change the name of the encrypted data container. Its default name is adyen-encrypted-data.
  • Submit the form using AJAX instead of the default submit action, as shown in this example:
var encryptedBlobFieldName = "myFieldName";

options.name = encryptedBlobFieldName;
options.onsubmit = function(e) {
    var encryptedData = form.elements[encryptedBlobFieldName].value;
    // ... Your AJAX code here ....
    e.preventDefault();
};

adyen.createEncryptedForm(form, options);

The public key is associated with the Web Service (ws) user account you use to submit the API payment request. If no key has been generated yet, you can create one from Customer Area.

For this, log in the Customer Area using your company-level account, go to Settings / Users, filter the list of users by System in the drop-down box, and then open the Web Service (ws) user page. On this page you can find the public key on the Easy Encryption pane, or (if the key is not available yet), click Generate and then Save (at the page bottom) to create a new key.

In case the HTML integration does not fulfill your setup requirements, the library has been split up into two parts since release V0_1_11. The newly introduced part is an HTML-independent encryption.

Make sure you encrypt the card data before sending to your server.

<script type="text/javascript" src="js/adyen.encrypt.nodom.min.js"></script>
<script type="text/javascript">
(function() {
    var key     =   "your key as retrieved from the Adyen Customer Area Web Service user page"; 
    var options = {}; // See adyen.encrypt.nodom.html for details

    var cseInstance = adyen.encrypt.createEncryption(key, options);

    function encryptMyData() {

        var postData = {};

        var cardData = {
            number : cardNumber,
            cvc : cvc,
            holderName : holderName,
            expiryMonth : expiryMonth,
            expiryYear : expiryYear,
            generationtime : generationtime
        };

        postData['adyen-encrypted-data'] = cseInstance.encrypt(cardData);

        // AJAX call or different handling of the post data.
    }

})();
</script>


The public key is associated with the Web Service (ws) user account you use to submit the API payment request. If no key has been generated yet, you can create one from Customer Area.

For this, log in the Customer Area using your company-level account, go to Settings / Users, filter the list of users by System in the drop-down box, and then open the Web Service (ws) user page. On this page you can find the public key on the Easy Encryption pane, or (if the key is not available yet), click Generate and then Save (at the page bottom) to create a new key.

Endpoints

When integrating with the Adyen payments platform, you can use either generic or custom endpoint to communicate with our API. 

For more information on fields and endpoints, refer to PaymentRequest and Payments API respectively.

Request

The additionalData object in the payment authorisation request needs to include the encrypted data that stores the credit card information. To encrypt the card data include card.encrypted.json in the additionalData. Include adyen.encrypted.data value to the card.encrypted.json key element when you send the request.

card.encrypted.json can hold the encrypted card data and timestamp:

  • Card holder
  • Card number
  • CVC
  • Expiry date
  • Generation time

When the shopper clicks Pay, the CSE library sends the encrypted data to your server. Make a server-to-server call to request a payment to Adyen. 

Before submitting a payment request to Adyen, make sure that the card.encrypted.json value is not null, false, or undefined.

The below examples show you how to make a payment request using JSON and SOAP.

curl -u "ws@Company.YourCompany":"YourWsPassword" \
   -H "Content-Type: application/json" \
   -X POST \
   --data \
   '{
       "additionalData": {
           "card.encrypted.json":"adyenjs_0_1_4p1$..."
       }
     ,
       "amount" : {
           "value" : 20000,
           "currency" : "EUR"
       },
     
       "reference" : "Your Reference Here",
       "merchantAccount" : "TestMerchant"
   }'\
   https://pal-test.adyen.com/pal/servlet/Payment/v30/authorise
curl -u "ws@Company.YourCompany":"YourWsPassword" \
  -H "Content-Type: application/soap" \
  -X POST \
  --data \
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soap:Body>
      <ns1:authorise xmlns:ns1="http://payment.services.adyen.com">
         <ns1:paymentRequest>
            <additionalData xmlns="http://payment.services.adyen.com">
               <entry>
                  <key xsi:type="xsd:string">card.encrypted.json</key>
                  <value xsi:type="xsd:string">Your generated key string from the JavaScript encryption... adyenjs_0_1_1$eGcJxidHkg5LYQ...6LUio9RipqyTBu11MJIC+rlMYxituYCT7A9yDeF2Rlv2I56KOAap66tTm2uZkto4PKRW4YCA8dZYQ ==</value>
               </entry>
            </additionalData>
            <amount xmlns="http://payment.services.adyen.com">
               <currency xmlns="http://common.services.adyen.com">EUR</currency>
               <value xmlns="http://common.services.adyen.com">2000</value>
            </amount>
            <merchantAccount xmlns="http://payment.services.adyen.com">TestMerchant</merchantAccount>
            <reference xmlns="http://payment.services.adyen.com">Your Reference Here</reference>
            <shopperEmail xmlns="http://payment.services.adyen.com">s.hopper@test.com</shopperEmail>
            <shopperIP xmlns="http://payment.services.adyen.com">61.294.12.12</shopperIP>
            <shopperReference xmlns="http://payment.services.adyen.com">Simon Hopper</shopperReference>
         </ns1:paymentRequest>
      </ns1:authorise>
   </soap:Body>
</soap:Envelope>
https://pal-test.adyen.com/pal/servlet/Payment/v30/authorise

Response

If the message passes validation, Adyen performs a risk analysis. Depending on the outcome, we attempt authorisation, and you receive a payment response. The response includes a PSP reference that uniquely identifies each payment and can be used later for capture, cancel, or refund.



For other possible response codes and fields of the payment response, refer to PaymentResult.







{
  "pspReference": "8814689190961342",
  "resultCode": "Authorised",
  "authCode": "83152"
}