Introduction
Worldline Sips is a secure multi-channel e-commerce payment solution that complies with the PCI DSS standard. It allows you to accept and manage payment transactions by taking into account business rules related to your activity (payment on dispatch, deferred payment, recurring payment, payment in instalments, …).
Document purpose
This document purpose is to explain the implementation of the Client Side Encryption solution until production starts.
Client Side Encryption functionally allows sensitive information (card number and csc code) to be encrypted and to process them throw Sips Office.
This functionality allow you to lower PCI requirement and therefore to only be subject to SAQ A-EP type impacts (see: https://www.pcisecuritystandards.org/pci_security/completing_self_assessment)
Who does this document target?
This document is intended for the merchants who want to integrate the Worldline Sips solution in a quick, simple way. Client Side Encryption allows to manage payment pages having data card that doesn't transit on your server and therefore lower the PCI requirement.
For an overview of the Worldline Sips solution, it's recommended to consult following documentation
- Functional presentation.
- Feature configuration guide.
Prerequisites
A good knowledge of one industry standard web programming language such as Java, PHP or .Net is required.
Secret key management
Upon your subscription, Worldline provides a secret key on the Merchant Extranet that will allow you to secure exchanges between your website and the Worldline Sips server.
You are responsible for looking after this key and should take all measures to:
- restrict access to the key
- safeguard it by encrypting it
- never copy it onto a non-secure disc or device
- never send it (via e-mail or regular mail) in a non-secure method
A secret key compromised (and used by a malicious third party) might disrupt the regular operation of your shop and might in particular generate unauthorised sales or cash transactions (e.g. refunds).
The very same secret key is used on the various Sips Paypage, Sips Office, Sips In-App and Sips Walletpage connectors.
keyVersion
field with the new
version, otherwise you will get an answer code 34 (suspected
fraud).CSE key managment
Worldline Sips Client Side Encryption require an encryption key. Like the Secret key, the CSE key is provided on the Sips Download extranet.
Contacting the support
For any technical question or request for assistance, our services are available:
- by telephone at: +33 (0) 811 10 70 33
- by e-mail: sips@worldline.com
In order to facilitate the processing of your requests, please provide your merchantId (15-digit number).
Understanding payment using Client Side Encryption
Client Side Encryption consists of Javascript library embedded on your payment page. It encrypts sensitive data before the web form is submitted to your server.
Encrypted data are then used to make a call to Sips Office card payment services in order to be processed
CSE functionality brings you following advantages:
- It's not mandatory to redirect customers to an external payment page
- PCI requirement is lowered since no plain sight sensitive data transits on your server.
1. The payment form included the CSE Javascript library and the public key. Card data are processed by the library and encrypt using the key.
2. You collect payment details.
3. You send the card data to Worldline Sips to process the transaction.
4. The Worldline Sips server deciphers encrypted data using the CSE private key part and process the payment.
5. The Worldline Sips server sends a response to allows you to display the payment result.
Implementing Client Side Encryption in 4 steps
Implementing CSE is an optional Sips Office (SOAP/JSON) feature.
In order to start with Sips Office, please refer to its dedicated documentation.
The CSE feature is available for cardOrder
, cardCheckEnrollment
, addCard
functions when the panType
field is set to CSE and for
walletOrder
, walletCheckEnrollment
functions when the
cscType
field is set to
CSE
Include SDPX CSE library
In order to use CSE functionality, you should include the Worldline Sips encryption library in the <head> tag of your payment page.
There are two ways to proceed:
- Standard JavaScript inclusion
<script type="text/javascript" src="https://office-server.sips-services.com/scripts/cse/latest/sdpx.encrypt.js"></script>
- Inclusion using the AMD module
The encryption library is compatible with AMD and can be used with any AMD module or library like RequireJS.
RequireJS recommend to include you script this way:
<script data-main="scripts/main" src="scripts/require.js"></script>
This will guaranty you a single entry point for your application since the your script data-main will be load async
Then, inside main.js, you can use the function require in order to load the encryption library.
<script> require(['https://office-server.sips-services.com/scripts/cse/latest/sdpx.encrypt.js'], function(sdpx) { // ... }); </script>
In the following example, the first require function parameter is an array of dependency modules needed for your applicaiton. The module name (i.e scripts/sdpx.encrypt ) represents the JS file without the filename extension.
If wanted, you can configure RequireJS in order for it to map the path for practicalness:
<script> requirejs.config({ baseUrl: './', paths: { 'sdpx.encrypt': 'https://office-server.sips-services.comscripts/cse/latest/sdpx.encrypt' } }); require(['sdpx.encrypt'], function(sdpx) { // ... }); </script>
Implement the payment HTML form
<!DOCTYPE html>
<html lang="en">
<head>
<title>Merchant payment page</title>
</head>
<body>
<form id="payment-form">
<input type="text" id="card-number" sdpx-encrypted />
<input type="text" id="card-expiry-month" />
<input type="text" id="card-expiry-year" />
<input type="text" id="card-csc-value" sdpx-encrypted />
<input type="submit" value="Checkout"/>
</form>
</body>
</html>
Currently Worldline Sips card payment services support card number and csc code field.
Link the payment form validation event to the CSE library
<script>
var paymentFormId = 'payment-form';
var merchantCseKeyValue = '00CE1A815AA0E970EB6E70...9434E9578F000308AD1E1B|010001';
var merchantCseKeyVersion = '2';
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentFormId, merchantCseKeyValue, merchantCseKeyVersion);
</script>
onSubmitEncryptForm should be called after the page loading.
This means that the above script should be inserted at the end of the <body> section or differed using, either, the onload property on the <body> element, or a listener addition in order to detect the end of the DOM loading of the page (see DOMContentLoaded and readystatechange).
document.onreadystatechange = function () {
if (document.readyState === "interactive") {
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentFormId, merchantCseKeyValue, merchantCseKeyVersion);
}
}
Testing on the customer's test environment
The test and integration steps can be implemented using the test environment.
The URL for the test environment is: https://office-server.test.sips-services.com
The following IDs must be used to carry out this test:
Merchant ID | 201040040170001 |
Secret key version | 1 |
Secret key | rxSP61eeP_oNi5TxCD7Ngy9YcwC8MLw6OlmFGGcsY54 |
CSE key version | 4 |
CSE key | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCEKMi77r/crSp4cTBrjTLA99JHL44cmnmlHp1Oon8vkrxjLZi1xAUTlNNERO+6trdJSxcCFsuWyAmL9KufFNmYjnHRTNQQc9dVVkg4e/iH5kEHJgaHn+6xyNP+VG62YTYNMqoA0Ctkg6eaRwukmsJtT4Ied/tudYYiQTzmehOWc2QPOqCQznuRYtRSGddwNj9BaMQYg0b9PG1uTS/EVAq1Ew9tJeNiL+0MvjEAYt9YNbVfbpOWuCAmveiyuvIPt0vrteE0Q32EkiqbvDPF0yjzjCc7aqA3UYNMKLgJBn0Rae86QNSSe6GJyPMURPVjC327LyPCT/11lu71usdn3t6hAgMBAAECggEARo4vfIWd0IZyYhKrsv+S1Qp5LJ/q0sJ1pv2NJeoC1LcV9CznlkKsIyQVFiFnitr5RxvbkLXywvDQh/N7nFZZROTnRsIphQ8TKvABZoZozMTUeqiGW+m6WRfKdcFFygBkBu/BauW4BNV0qRy8zogAvLLx2KpdhT8g+TCy/qi1xF/YX6iuN5A3puvV5B4VWNocTaXemGCqDjoJsH6w5ajdqQ6iY4U5zvthuWXG0Ct+jnXlC/mXz610kIb5U+bGvnBWZwHRduDE73zVi6ztoyqEXqQcCdJEetbUa6P5feX8UfDqvTXcJngnsZgZ2NxJP7KmGLKlP293c7b/LDtb4CwhAQKBgQDQccZFMmiIsWOddVjq3OPbDsjefPRxSp/rKi2ankafVed+R9PD5He4bD8Iy4otSW+tUeu0NbDecUKAO3Nzl19H1fu7sSUWwZBAQCfTkZSITVtdZ5m8U/eqyyxAmBJh7Jr5umwwPvGqH4lX65qKuHt0R66k7dMb0QVIEF29gFh8aQKBgQCiT5Ec4axIk1mV3SndkbdTT/azmlWKhLhBN0W1IpYDqgETOP28a5CwkVcHvCG5+Y0yvWq6jTZngfIpI9Z5XmP65leKvgRp3LhrAzQxuiQObAEBN0644vI+zcfHAUYYr5WXIFtRylyHKaDG9vvSkJp44EhYxHkzr0rGZKC7nj1peQKBgCCxZ56czGZ8JBqjOCIGKTrHc9vpj1FhmfmBcQuqPXtqNtfInj9AS0LCv5Q6kF6QARMXITfvn+ETtJF2QaJkoI4c0tHac+3AyEY7icOWNsy2DVl2EVfHd7XzDerHr0JqoNgAVE2w4aiEL795dZDCZKKVR6AYqR7YxtJJttotEjPZAoGAOETdSeXylDaBGDNUEDw0Ee3m2NzoSt04A2PmBqW23A5T0RYw4OFph8zbHxNZnd+l07FXDtVlxvyFtz11XR4cCx9Pugml/g1G4dJ6hcLCPT20G3fREseas6sjVxpZ8rTsZzgQcIp3CWSlGFUHeDgpVT5r1lpGqmRax+yazHBPWgECgYBH2iihySqNmHmNgi58j7p3UC1n0sPbXgmb74igi1J1vYX/8n6ysPTAc0kRPUv18JUkDCqnZbJLoCyGfSfL5geWhyfkr8mQDVrrtD68dfdoozm2GMKePXCNg1CWS8+LTFqN3PWcbHv2hcsiHxsLSTds1lTJLYstdefyXZ+avsBUxg== |
Advanced implementation
Fields validation activation
The SDPX CSE library can be used to validate input fields on the client side. The functionality is not activated by default, but it can be useful since encrypted data can't by validated on your server.
In order to activate client side field validation an array including fields definition to be checked can be embedded within the object returning be the function onSubmitEncryptForm. An array cell is a JSON structure with the following properties:
Property | Mandatory | Description |
---|---|---|
id | yes | Id of the HTML to be checked |
validator | yes | default validator or custom function to be used to check the field value |
onSuccess | no | callback triggered on a successful field validation |
onError | no | callback triggered on erroneous field validation |
<script>
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentForm, merchantCseKeyValue, merchantCseKeyVersion);
var fieldValidationDefs = [
{ id: 'card-number', validator: '@CardNumber', onSuccess: successValidationHandler, onError: errorValidationHandler },
{ id: 'card-csc-value', validator: '@CscValue', onSuccess: successValidationHandler, onError: errorValidationHandler },
{ id: 'card-expiry-month', validator: '@ExpiryMonth', onSuccess: successValidationHandler, onError: errorValidationHandler },
{ id: 'card-expiry-year', validator: '@ExpiryYear', onSuccess: successValidationHandler, onError: errorValidationHandler }
/*
// Custom validator example:
{ id: 'card-expiry', validator: customCardExpiryValidator, onSuccess: successValidationHandler, onError: errorValidationHandler }
*/
];
paymentForm.setValidations(fieldValidationDefs);
/**
* Custom validator example: check the card expiry value (format 'mm/yyyy')
*
* @param {value} the HTML input element value to validate
* @return {boolean} true if the value is valid, false otherwise
*/
function customCardExpiryValidator(val) {
// Validate the card expiry value
return /^[0-9]{2}\/[0-9]{4}$/.test(val);
}
/**
* Handle success validation
*
* @param {element} the HTML element that has been successfully validated
* @return {void}
*/
function successValidationHandler(element) {
// Do sthg if needed
}
/**
* Handle error validation
*
* @param {Error} a JSON object containing error information
* @return {void}
*/
function errorValidationHandler(error) {
// Handle error
}
</script>
Default field validator
Reference | Description | Source code |
---|---|---|
@CardNumber | Check that card number is between 6 and 19 digits | return /^[0-9]{6,19}$/.test(val); |
@CscValue | Check that csc code is between 3 and 4 digits | return /^[0-9]{3,4}$/.test(val); |
@ExpiryMonth | Check that the month is in range 1 to 12. | return /^[0-9]{2}$/.test(val) && (val > 0) && (val <= 12); |
@ExpiryYear | Check to the year is valid | return /^[0-9]{4}$/.test(val) && (val >= (new Date()).getFullYear()); |
JSON object description reminder
Reference | Description | Exemple |
---|---|---|
message | error message('is invalid!') | card-number is invalid! |
validator | validator reference or custom function name used to validation | @CardNumber, customCardExpiryValidator, ... |
element | HTML element to be checked | HTMLElement |
reason | JavaScript error object describing the validation failure | Error:* Error('Validation returns false')* Error('No validator found for element [<field-id>]') |
Error management
By default, when facing an incident linked to the library usage, a JavaScript error is intercepted and the form submission is canceled.
In order to be able to deal with it, a callback function can be attached to the object returned by onSubmitEncryptForm.
<script>
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentForm, merchantCseKeyValue, merchantCseKeyVersion);
paymentForm.setErrorHandler(errorHandler);
function errorHandler(error) {
// Display an error message to the end user and send information to your server
}
</script>