data-collector/index.js

'use strict';
/* eslint-disable camelcase */
/** @module braintree-web/data-collector */

var kount = require('./kount');
var fraudnet = require('./fraudnet');
var BraintreeError = require('../lib/error');
var methods = require('../lib/methods');
var convertMethodsToError = require('../lib/convert-methods-to-error');
var packageVersion = require('package.version');

/**
 * @class
 * @global
 * @name DataCollector
 * @description instance returned by {@link module:braintree-web/data-collector.create create}
 * @classdesc This class is used for advanced fraud integration with PayPal and Kount. Instances of this class have {@link DataCollector#deviceData|deviceData} which is used to correlate user sessions with server transactions.
 */

/**
 * @memberof DataCollector
 * @name deviceData
 * @type string
 * @description JSON string to pass with server transactions
 * @instance
 */

/**
 * @memberof DataCollector
 * @name teardown
 * @function
 * @description Cleanly remove all event handlers and DOM nodes that were added
 * @param {errback} [callback] Called once teardown is complete. No data is returned if teardown completes successfully.
 * @instance
 * @returns {void}
 */

/**
 * @function
 * @param {object} options Object containing all {@link DataCollector} options
 * @param {object} [options.kount] If supplied, Kount fraud capabilities are enabled
 * @param {string} options.kount.environment Which Kount environment to operate in. Options are "sandbox" or "production"
 * @param {string} [options.kount.merchantId] If using a direct Kount integration, your Kount-provided merchantId
 * @param {boolean} [options.paypal] If true, PayPal fraud capabilities are enabled
 * @param {errback} callback The second argument, <code>data</code>, is the {@link DataCollector} instance
 * @returns {void}
 * @static
 */
function create(options, callback) {
  var data, kountInstance, fraudnetInstance, result;
  var instances = [];

  function teardown(cb) {
    var i;

    for (i = 0; i < instances.length; i++) {
      instances[i].teardown();
    }

    convertMethodsToError(result, methods(result));

    if (cb) {
      cb();
    }
  }

  if (options.kount != null) {
    try {
      kountInstance = kount.setup(options.kount);
    } catch (err) {
      callback(new BraintreeError({
        message: err.message,
        type: BraintreeError.types.MERCHANT
      }));
      return;
    }

    data = kountInstance.deviceData;
    instances.push(kountInstance);
  } else {
    data = {};
  }

  if (options.paypal === true) {
    fraudnetInstance = fraudnet.setup();
    data.correlation_id = fraudnetInstance.sessionId;
    instances.push(fraudnetInstance);
  }

  if (instances.length === 0) {
    callback(new BraintreeError({
      type: BraintreeError.types.MERCHANT,
      message: 'Data Collector must be created with Kount and/or PayPal.'
    }));
    return;
  }

  result = {
    deviceData: JSON.stringify(data),
    teardown: teardown
  };

  callback(null, result);
}

module.exports = {
  create: create,
  /**
   * @description The current version of the SDK, i.e. `{@pkg version}`.
   * @type {string}
   */
  VERSION: packageVersion
};