For integrating with the supported version of ravelinjs, please see the ravelinjs v1 usage guide.
Ravelin provides a means of sending payment methods to Ravelin without having to handle sensitive cardholder data within the scope of the Payment Card Industry Data Security Standards (PCI DSS). The library is intended to work on web pages where you have access to the primary account number (PAN) that the customer has entered for a payment method. Passing through the encrypted values provided by this library avoids your servers handling any sensitive cardholder data, helping reduce the scope of your PCI compliance.
This is achieved through our publically available ravelinjs library which is responsible for performing the client-side encryption, as well as loading in Ravelin’s device tracking and session tracking functionality.
We recommend using ravelinjs in scenarios for which you are currently using the client-side encryption or client-side tokenisation features provided by your payment gateway. For scenarios in which payment details are captured within an iframe or a hosted payment form that contains iframe inputs, ravelinjs will not have access to the card details, and no effort should be made to attempt to circumvent the additional security these iframes provide.
The ravelinjs library can be used as a dependency in AMD modules; imported into scripts bundled using webpack; or by dropping a script tag into your web page.
We strongly advise reading our security recommendations before implementing ravelinjs to ensure any security risks involved in this process are minimised.
src/index.html
...
<script src="./common.js"></script>
<script src="./require.js"></script>
<script>
require(['ravelin'], function(ravelin) {
ravelin.setRSAKey('REDACTED');
document.getElementById('form').onsubmit = function() {
var month = document.getElementById('month');
output(function() {
return ravelin.encrypt({
nameOnCard: document.getElementById('name').value,
pan: document.getElementById('number').value,
month: month.options[month.selectedIndex].value,
year: document.getElementById('year').value,
});
});
return false;
};
})
</script>
src/index.js
import ravelin from './ravelin.js';
import output from './common.js';
ravelin.setRSAKey('REDACTED');
document.getElementById('form').onsubmit = function() {
var month = document.getElementById('month');
output(function() {
return ravelin.encrypt({
nameOnCard: document.getElementById('name').value,
pan: document.getElementById('number').value,
month: month.options[month.selectedIndex].value,
year: document.getElementById('year').value,
});
});
return false;
};
src/index.html
...
<script src="bundle.js"></script>
...
src/index.html
...
<script src="./ravelin.js"></script>
...
In order for ravelinjs to perform optimally and correctly associate events to specific customers and orders, several variables need to be set. These are described below:
Before any other methods are called, setFallbackJS()
can be called to provide a lightweight session-tracker. This mitigates the loss of device tracking should ravelin.net be blocked by your customer’s browser. To use it, host a copy of https://cdn.ravelin.net/js/rvn-0.1.18-lite.min.js on your local domain–or another allowed by your Content-Security-Policy–and pass this address to setFallbackJS()
:
<script src="ravelin.min.js"></script>
<script>
ravelinjs.setFallbackJS('/rvn.js');
...
</script>
Before any track methods are called, setPublicAPIKey()
should be called with the Publishable (Public) API Key found in the Developer section of your account.
This authenticates subsequent method calls to our API, and is therefore required.
If you are carrying out any testing, please ensure that the Publishable API Key from your Sandbox account is used.
Important: Please ensure that only the Publishable API Key is used. The Secret API Key should never be used with ravelinjs.
<script src="ravelin.min.js"></script>
<script>
// Setting Publishable (public) API Key
ravelinjs.setFallbackJS('/rvn.js');
ravelinjs.setPublicAPIKey('pk_live_...');
...
</script>
If card encryption is to be used, setRSAKey()
needs to be called with the RSA key found in the Developer section of your account.
If this is not present, please let us know and we can create one for you.
The Public RSA key that is set encrypts the PAN passed to the encrypt method.
<script src="ravelin.min.js"></script>
<script>
// Setting RSA key
ravelinjs.setFallbackJS('/rvn.js');
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setRSAKey('10010|abc123...xyz789');
...
</script>
When the Publishable API Key has been set, ravelinjs generates and stores a cookie containing the customer’s deviceID in the customer’s browser.
Within this cookie is a field called ravelinDeviceId
, which contains the deviceId
that should be sent in requests to the Ravelin API for this customer.
In order for the cookie containing the customer’s deviceId to be valid for your domain name, setCookieDomain()
should be called and set at as high a level as possible, e.g. mysite.com
rather than subdomain.mysite.com
.
<script src="ravelin.min.js"></script>
<script>
// Setting cookie domain
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setCookieDomain('mysite.com');
...
</script>
For Ravelin to associate tracked pages to specific clients, the customerId should be set using setCustomerId()
before either of the tracking methods are called.
<script src="ravelin.min.js"></script>
<script>
// Set customerId
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setCustomerId("example@ravelin.com");
...
</script>
If the customerId is not known, for example if the customer is not logged in, then a temporary customerId can be set with setTempCustomerId()
.
<script src="ravelin.min.js"></script>
<script>
// Set temporary customerId
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setTempCustomerId("SESSION_12345");
...
</script>
As soon as a customerId is available, a (Login (v2)) request should be sent that associates the tempCustomerId
to the customerId
:
{
"timestamp": 1552400674,
"customerId": "example@ravelin.com",
"tempCustomerId": "SESSION_12345"
}
For site activity to be associated to a particular order, setOrderId()
should be called with the appropriate orderId before either of the tracking methods are called.
<script src="ravelin.min.js"></script>
<script>
// Set orderId
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setOrderId("order_12345");
...
</script>
The primary goal of ravelinjs is to allow the secure sharing of card information with Ravelin without handling PCI-compliant data. Prior to calling ravelinjs.encrypt()
, the RSA key from your developer dashboard should be set using the setRSAKey()
method.
When this is set and card details are available, encrypt the values to send to Ravelin using ravelinjs.encrypt({pan, month, year, nameOnCard})
.
pan
, month
, year
are required, while nameOnCard
is optional, and no other properties are allowed on the object. Validation is performed, confirming that expiry dates are valid, the PAN is at least 13 characters, and that no addition fields are present. Should any validation checks fail, an exception is raised.
For a worked example of how cards should be encrypted, please see the end-to-end example.
A crucial part of device tracking with ravelinjs is the fingerprinting process, whereby information about the customer’s browser is extracted and sent to the Ravelin API. Ensure that the customerId
is set before trackFingerprint()
is called. If it is not set, it can also be set when calling trackFingerprint()
.
<script src="ravelin.min.js"></script>
<script>
// Fingerprinting
ravelinjs.setFallbackJS('/rvn.js');
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setCustomerId("examplecustomer@ravelin.com")
ravelinjs.trackFingerprint();
// Setting customerId on method call:
// ravelinjs.trackFingerprint("examplecustomer@ravelin.com")
...
</script>
The following code snippet demonstrates how Ravelin can be notified of the current page the customer is on. Typically we suggest this is called on page load on pages involved in the order flow – search result, basket, billing/payment and shipping info pages, and so on.
In order for Ravelin to associate the tracked page to a particular customer and order, ensure that setCustomerId()
and setOrderId()
are called if the customer and order IDs are known.
<script src="ravelin.min.js"></script>
<script>
// Tracking
ravelinjs.setFallbackJS('/rvn.js');
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setCustomerId("examplecustomer@ravelin.com");
ravelinjs.setOrderId("order_12345");
ravelinjs.trackPage();
...
</script>
The track()
method is similar to trackPage()
but takes an additional parameter which can be used to set the name of the event being tracked. As with trackPage()
, setCustomerId()
and setOrderId()
should be called first.
<script src="ravelin.min.js"></script>
<script>
// Tracking
ravelinjs.setFallbackJS('/rvn.js');
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.setCustomerId("examplecustomer@ravelin.com");
ravelinjs.setOrderId("order_12345";
ravelinjs.track('Checkout page');
...
</script>
Both the track()
and trackPage()
methods can be passed a JSON object containing additional metadata about the page being tracked. This is particularly useful if the URL or page title provides basic information about the page being tracked.
<script src="ravelin.min.js"></script>
<script>
// Tracking
ravelinjs.setFallbackJS('/rvn.js');
ravelinjs.setPublicAPIKey('pk_live_...');
ravelinjs.track('CUSTOMER_SEARCHED', { searchTerm: 'product' });
...
</script>
In the following form, we collect card details from the customer, encrypt them and send the encrypted values (the ciphertext) back to your server.
<!-- Browser -->
<form id="form-payment-card">
Card Number: <input name="pan" />
CVV: <input name="cvv" />
Name: <input name="nameOnCard" />
Month: <input name="month" />
Year: <input name="year" />
<input type="hidden" name="ravelinCipherText" />
<input type="submit" />
</form>
<script src="ravelin.min.js"></script>
<script>
// Encryption
ravelinjs.setRSAKey("..|.....")
document.getElementById('form-payment-card').onsubmit = function() {
this.ravelinCipherText.value = ravelinjs.encrypt({
pan: this.pan.value,
month: this.month.value,
year: this.year.value,
nameOnCard: this.nameOnCard.value,
});
// Avoid sending sensitive data to your server.
this.pan.value = this.cvv.value = this.name.value = '';
};
</script>
Once the ciphertext is received by your server, the API request to Ravelin in which a fraud recommendation is requested should use this ciphertext value:
/* Server-side */
var card = JSON.parse(form.getValue('ravelinCipherText'));
var action = request("https://pci.ravelin.com/v2/checkout?score=checkoutPreAuth", {
// ...
"paymentMethod": card,
});
Was this page helpful?