Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ This code makes heavy use of [jsonix](https://github.com/highsource/jsonix) to g
To add a new version, simply drop the XSD files in the `xsd` directory, add any relevant `jaxb` customizations to a file in the `bindings` directory, and run:

```bash
npm run build
npm run generate
```
16 changes: 16 additions & 0 deletions bindings/v12_10.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc">

<jaxb:globalBindings generateElementProperty="false">
<jaxb:javaType name="java.util.Calendar" xmlType="xs:date"
parseMethod="com.cnp.sdk.JAXBConverters.parseDate" printMethod="com.cnp.sdk.JAXBConverters.printDate" />
<jaxb:javaType name="java.lang.Long" xmlType="xp:transactionAmountType"
parseMethod="com.cnp.sdk.JAXBConverters.parseLong" printMethod="com.cnp.sdk.JAXBConverters.printLong" />
<jaxb:javaType name="java.lang.String" xmlType="xs:base64Binary"
parseMethod="com.cnp.sdk.JAXBConverters.parseString" printMethod="com.cnp.sdk.JAXBConverters.printString" />
<xjc:simple />
</jaxb:globalBindings>

</jaxb:bindings>
16 changes: 16 additions & 0 deletions bindings/v9_14.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc">

<jaxb:globalBindings generateElementProperty="false">
<jaxb:javaType name="java.util.Calendar" xmlType="xs:date"
parseMethod="com.litle.sdk.JAXBConverters.parseDate" printMethod="com.litle.sdk.JAXBConverters.printDate" />
<jaxb:javaType name="java.lang.Long" xmlType="xp:transactionAmountType"
parseMethod="com.litle.sdk.JAXBConverters.parseLong" printMethod="com.litle.sdk.JAXBConverters.printLong" />
<jaxb:javaType name="java.lang.String" xmlType="xs:base64Binary"
parseMethod="com.litle.sdk.JAXBConverters.parseString" printMethod="com.litle.sdk.JAXBConverters.printString" />
<xjc:simple />
</jaxb:globalBindings>

</jaxb:bindings>
24 changes: 14 additions & 10 deletions certification.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"use strict";

var litle = require('./lib/Litle.js')({});
var litle = require('./lib/Litle.js')({
user: process.env.LITLE_CERTIFICATION_USER,
password: process.env.LITLE_CERTIFICATION_PASSWORD,
log: true,
});

litle.litleOnlineRequest.sale({
id: 'Sale Id',
Expand All @@ -24,7 +28,7 @@ litle.litleOnlineRequest.sale({
cardValidationNum: '349'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand Down Expand Up @@ -52,7 +56,7 @@ litle.litleOnlineRequest.sale({
authenticationValue: 'BwABBJQ1AgAAA AAgJDUCAAAAAA A='
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -78,7 +82,7 @@ litle.litleOnlineRequest.sale({
cardValidationNum: '758'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -103,7 +107,7 @@ litle.litleOnlineRequest.sale({
expDate: '0414'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -122,7 +126,7 @@ litle.litleOnlineRequest.sale({
authenticationValue: 'BwABBJQ1AgAAA AAgJDUCAAAAAA A='
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -148,7 +152,7 @@ litle.litleOnlineRequest.sale({
cardValidationNum: '992'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -174,7 +178,7 @@ litle.litleOnlineRequest.sale({
cardValidationNum: '251'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -200,7 +204,7 @@ litle.litleOnlineRequest.sale({
cardValidationNum: '184'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


Expand All @@ -226,7 +230,7 @@ litle.litleOnlineRequest.sale({
cardValidationNum: '0421'
}
}, function(err, res){
console.log(res);
console.log({err,res});
});


136 changes: 136 additions & 0 deletions lib/CNPOnlineRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
'use strict';

var url = require('url');
var https = require('https');
var Jsonix = require('jsonix').Jsonix;

function CNPOnlineRequest (config, mapping) {
var self = this;


// Here we override the Long type to use strings, since javascript has a number precision
// limit of 32 bits, which causes silent truncation of significant values. See bug at
// https://github.com/highsource/jsonix-schema-compiler/issues/77
mapping = Object.assign({}, mapping, {typeInfos: [
new (Jsonix.Class(Jsonix.Schema.XSD.String, {
name : 'Long',
typeName : Jsonix.Schema.XSD.qname('long'),
CLASS_NAME : 'Long'
}))()
].concat(mapping.typeInfos)});

self._config = config;

var jsonixConfig = {
mappingStyle: 'simplified',
namespacePrefixes: {
'http://www.vantivcnp.com/schema': ''
}
};

self._context = new Jsonix.Context([mapping], jsonixConfig);

mapping.elementInfos

// only add methods for types that are valid choices for a baseRequest
.filter(function(el) {
return el.substitutionHead === 'transaction';
})

.forEach(function(el) {
self[el.elementName] = function(data, callback) {
self._send({
transaction: {
name: {
namespaceURI: 'http://www.vantivcnp.com/schema',
localPart: el.elementName,
},
value: data
}
}, callback);
};
});
}

CNPOnlineRequest.prototype._send = function _send(data, callback){
var self = this;

// merge any configured data
data = Object.assign({

// set top level attributes
version: this._config.version,
xmlns: 'http://www.vantivcnp.com/schema',
merchantId: this._config.merchantId || this._config.currency_merchant_map.DEFAULT,

// set authentication
authentication: {
user: this._config.user,
password: this._config.password
}

}, data);

data = {
name: {
namespaceURI: 'http://www.vantivcnp.com/schema',
localPart: 'cnpOnlineRequest'
},
value: data
};

var marshaller = this._context.createMarshaller();
var unmarshaller = this._context.createUnmarshaller();

var requestBody;

// marshal the request body
try { requestBody = marshaller.marshalString(data); }
catch (err) { return callback(err); }

// build the http request
var reqOptions = url.parse(this._config.url);
reqOptions.method = 'POST';
reqOptions.headers = {'Content-Type': 'application/xml'};

var req = https.request(reqOptions, function(res) {
if (res.statusCode != 200)
return callback('Request failed');

res.setEncoding('utf8');

var response = '';
res.on('data', function (chunk) {
response += chunk;
});

res.on('end', function() {
var responseBody;

// unmarshal the response body
try { responseBody = unmarshaller.unmarshalString(response); }
catch (err) { return callback(err); }

// check the response type
if (!responseBody.cnpOnlineResponse)
return callback(new Error('Missing root cnpOnlineResponse node.'));

// check the response code
if (responseBody.cnpOnlineResponse.response === '1')
return callback(new Error(responseBody.cnpOnlineResponse.message));

// return the successful response
return callback(null, responseBody.cnpOnlineResponse.transactionResponse);
});
});

req.on('error', callback);

// send the request body
req.write(requestBody);

req.end();
};


module.exports = CNPOnlineRequest;
29 changes: 22 additions & 7 deletions lib/Litle.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var LitleOnlineRequest = require('./LitleOnlineRequest.js');
var CNPOnlineRequest = require('./CNPOnlineRequest.js');

function Litle(config) {
config = config || {};
Expand All @@ -17,21 +18,35 @@ function Litle(config) {
url: config.url || 'https://payments.vantivcnp.com/vap/communicator/online',
proxy_addr: config.proxy_addr || null,
proxy_port: config.proxy_port || null,
version: config.version || '9.10',
version: config.version || '12.10',
timeout: config.timeout || 65,
log: (typeof config.log == 'boolean') ? config.log : false,
merchantId: config.merchantId || 'default'
};

// import the mappings for the specified version
var v = ('' + this._config.version).replace('.', '_');
this._mappings = {
litleBatch: require('../mappings/litleBatch_v' + v)['litleBatch_v' + v],
litleOnline: require('../mappings/litleOnline_v' + v)['litleOnline_v' + v],
};

// add support for online requests
this.litleOnlineRequest = new LitleOnlineRequest(this._config, this._mappings.litleOnline);
// > '12.10'.localeCompare('9.14', undefined, {numeric: true, sensitivity: 'base'})
// 1
// > '9.14'.localeCompare('12.10', undefined, {numeric: true, sensitivity: 'base'})
// -1
if (~this._config.version.localeCompare('12.10', undefined, {numeric: true, sensitivity: 'base'})) {
this._mappings = {
litleBatch: require('../mappings/cnpBatch_v' + v)['cnpBatch_v' + v],
litleOnline: require('../mappings/cnpOnline_v' + v)['cnpOnline_v' + v],
};
// add support for online requests
this.litleOnlineRequest = new CNPOnlineRequest(this._config, this._mappings.litleOnline);
this.onlineRequest = new CNPOnlineRequest(this._config, this._mappings.litleOnline);
} else {
this._mappings = {
litleBatch: require('../mappings/litleBatch_v' + v)['litleBatch_v' + v],
litleOnline: require('../mappings/litleOnline_v' + v)['litleOnline_v' + v],
};
// add support for online requests
this.litleOnlineRequest = new LitleOnlineRequest(this._config, this._mappings.litleOnline);
}

// TODO: support batch processing?
}
Expand Down
11 changes: 7 additions & 4 deletions lib/LitleOnlineRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ function LitleOnlineRequest (config, mapping) {
}))()
].concat(mapping.typeInfos)});


self._config = config;
self._context = new Jsonix.Context([mapping], {

var jsonixConfig = {
mappingStyle: 'simplified',
namespacePrefixes: {
'http://www.litle.com/schema': ''
}
});
};

self._context = new Jsonix.Context([mapping], jsonixConfig);

mapping.elementInfos

Expand All @@ -37,7 +39,7 @@ function LitleOnlineRequest (config, mapping) {

.forEach(function(el) {
self[el.elementName] = function(data, callback) {
this._send({
self._send({
transaction: {
name: {
namespaceURI: 'http://www.litle.com/schema',
Expand All @@ -51,6 +53,7 @@ function LitleOnlineRequest (config, mapping) {
}

LitleOnlineRequest.prototype._send = function _send(data, callback){
var self = this;

// merge any configured data
data = Object.assign({
Expand Down
Loading