Skip to content

Commit

Permalink
Merge branch '0.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
kkamkou committed Aug 3, 2016
2 parents 1bb4532 + 7155299 commit d617ea3
Show file tree
Hide file tree
Showing 19 changed files with 429 additions and 89 deletions.
80 changes: 80 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
env:
node: true
es6: true

# enable ECMAScript features
ecmaFeatures:
blockBindings: true
templateStrings: true
octalLiterals: true
binaryLiterals: true
generators: true
forOf: true

rules:
# Possible Errors
# list: https://github.com/eslint/eslint/tree/master/docs/rules#possible-errors
## check debugger sentence
no-debugger: 2
## check duplicate arguments
no-dupe-args: 2
## check duplicate object keys
no-dupe-keys: 2
## check duplicate switch-case
no-duplicate-case: 2
## disallow assignment of exceptional params
no-ex-assign: 2
## disallow use of reserved words as keys like enum, class
quote-props: [2, "as-needed"]
## disallow unreachable code
no-unreachable: 2
## require valid typeof compared string like typeof foo === 'strnig'
valid-typeof: 2

# Best Practices
# list: https://github.com/eslint/eslint/tree/master/docs/rules#best-practices
## require falls through comment on switch-case
no-fallthrough: 2

prefer-const: 2

# Stylistic Issues
# list: https://github.com/eslint/eslint/tree/master/docs/rules#stylistic-issues
## use single quote, we can use double quote when escape chars
quotes:
- 2
- "single"
- "avoid-escape"
## 2 space indentation
indent:
- 2
- 2
## add space after comma
## set to 'warn' because of https://github.com/eslint/eslint/issues/2408
comma-spacing: 1
## put semi-colon
semi: 2
## require spaces operator like var sum = 1 + 1;
space-infix-ops: 2
## require spaces return, throw, case
keyword-spacing: 2
## no space before function, eg. 'function()'
space-before-function-paren: [1, {"anonymous": "always", "named": "never"}]
## require space before blocks, eg 'function() {'
space-before-blocks: [2, "always"]
## disallow dangling underscores in identifiers
no-underscore-dangle: 0
## require parens for Constructor
new-parens: 2
## max 100 length
max-len:
- 2
- 100
- 2

# Strict Mode
# list: https://github.com/eslint/eslint/tree/master/docs/rules#strict-mode
## 'use strict' on top
strict:
- 2
- "global"
53 changes: 34 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,69 @@ Concardis payments in Node.js
[![Coverage Status](https://coveralls.io/repos/github/kkamkou/node-concardis/badge.svg?branch=master)](https://coveralls.io/github/kkamkou/node-concardis?branch=master)
[![Dependency Status](https://www.versioneye.com/user/projects/5799df0ba9f08d0050d2ccae/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/5799df0ba9f08d0050d2ccae)

## Docs
- [hosted-tokenization-page](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/eee5a544-7860-4428-9956-150d1a64805f/hosted-tokenization-page.ashx)
- [alias-gateway](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/b5e53b03-49ff-4152-8df0-c14a02c1fdba/alias-gateway.ashx)
- [e-commerce](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/123ae0b9-2864-48d4-9b06-7ed2d70db029/e-commerce.ashx)
- [directlink](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/5fb19037-3393-4cea-bace-1fd21718119f/directlink.ashx)

## Examples

#### First steps
```js
const concardis = require('concardis');
````

#### Hosted tokenization page
### Hosted tokenization page

To be able to use the Hosted Tokenization Page, you need to have at least one of the following options enabled:
- One Page Checkout (option ID: OPC)
- Alias Manager (option ID: REC1, REC2, RECX)

```js
const conf = {
const payload = {
'account.pspid': 'MyPspid',
'card.paymentmethod': 'CreditCard',
'parameters.accepturl': 'http://ya.ru/succ',
'parameters.exceptionurl': 'http://ya.ru/err',
'account.pspid': 'myaccount'
'parameters.exceptionurl': 'http://ya.ru/err'
};
const url = concardis.hosted.UrlSmart.production('myshatoken', conf);
// or concardis.hosted.UrlSmart.test('myshatoken', conf, 'sha512')
const url = concardis.hosted.UrlSmart.production('MyShaToken', payload);
// or concardis.hosted.UrlSmart.test('myshatoken', payload, 'sha512')
console.log(url.toString());
```

#### SHA signature
### SHA signature
- SHA-256 (is used by default in `request.CollectionChecksum`)

```js
const checksum = new concardis.request.CollectionChecksum(
new concardis.request.ObjectCollection({'pspid': 'example'}), 'sha_phrase'/*, 'sha512'*/
);
console.log(checksum.toString());
```

### DirectLink (server-to-server)

#### Request a new order

```js
const payload = {
alias: 'FE521799-50BB-47E6-AA10-B7B15CB3A0CC',
amount: 7700,
currency: 'EUR',
cvc: '123', // or eci: 2/9
operation: 'SAL',
orderid: '1234567890',
pspid: 'MyPspid',
pswd: 'MyApiUserPassword',
userid: 'My-API-User'
};
concardis.directlink.OrderSmart
.test('MyShaToken', payload).toJson()
.then(response => console.log(response))
.catch(error => console.error(error))
```
// https://secure.payengine.de/ncol/prod/orderdirect.asp
// https://secure.payengine.de/ncol/prod/alias_gateway.asp
```

## Docs
- [hosted-tokenization-page](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/eee5a544-7860-4428-9956-150d1a64805f/hosted-tokenization-page.ashx)
- [alias-gateway](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/b5e53b03-49ff-4152-8df0-c14a02c1fdba/alias-gateway.ashx)
- [e-commerce](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/123ae0b9-2864-48d4-9b06-7ed2d70db029/e-commerce.ashx)
- [directlink](https://support-payengine.v-psp.com/~/media/kdb/pdf/concardis/en/5fb19037-3393-4cea-bace-1fd21718119f/directlink.ashx)

## License
The MIT License (MIT)
Expand Down
39 changes: 39 additions & 0 deletions lib/directlink/Order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Licensed under the MIT License
*
* @author Kanstantsin A Kamkou (2ka.by)
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @link https://github.com/kkamkou/node-concardis
*/

'use strict';

const xml2js = require('xml2js');

/*public abstract*/ class Order {
constructor(request) {
this._request = request;
}

toJson() {
return new Promise((resolve, reject) => {
this.toString()
.then(
xml =>
xml2js.parseString(xml, (err, json) =>
err ? reject(err) : resolve(json.ncresponse.$))
)
.catch(reject);
});
}

toString() {
return new Promise((resolve, reject) => {
return this._request.submit()
.then(response => resolve(response.toString()))
.catch(reject);
});
}
}

module.exports = Order;
39 changes: 39 additions & 0 deletions lib/directlink/OrderSmart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// .catch(e => setImmediate(() => { throw e; }));

/**
* Licensed under the MIT License
*
* @author Kanstantsin A Kamkou (2ka.by)
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @link https://github.com/kkamkou/node-concardis
*/

'use strict';

const OrderValid = require('./OrderValid'),
SignedHttp = require('../request/SignedHttp'),
SignedCollection = require('../request/SignedCollection'),
ObjectCollection = require('../request/ObjectCollection'),
CollectionChecksum = require('../request/CollectionChecksum');

const instance = (endpoint, secret, obj, algorithm) => {
const collection = new ObjectCollection(obj);
return new OrderValid(
new SignedHttp(
endpoint,
{timeout: 10000, method: 'POST', headers: {'User-Agent': 'node-concardis'}},
new SignedCollection(
'shasign',
new CollectionChecksum(collection, secret, algorithm),
collection
)
)
);
};

module.exports = {
test: (secret, obj, algorithm) =>
instance('https://secure.payengine.de/ncol/test/orderdirect.asp', secret, obj, algorithm),
production: (secret, obj, algorithm) =>
instance('https://secure.payengine.de/ncol/prod/orderdirect.asp', secret, obj, algorithm)
};
40 changes: 40 additions & 0 deletions lib/directlink/OrderValid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// .catch(e => setImmediate(() => { throw e; }));

/**
* Licensed under the MIT License
*
* @author Kanstantsin A Kamkou (2ka.by)
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @link https://github.com/kkamkou/node-concardis
*/

'use strict';

const Order = require('./Order');

/*public final*/ class OrderValid extends Order {
constructor(request) {
super(request);

const requiredIfNoAlias = ['CARDNO', 'ED', 'CVC'],
required = [
'PSPID', 'ORDERID', 'AMOUNT', 'CURRENCY', 'OPERATION', 'SHASIGN', 'USERID', 'PSWD'
];

required.forEach(k => {
if (!this._request.has(k)) {
throw new Error(`The "${k}" param is required`);
}
});

if (!this._request.has('ALIAS')) {
requiredIfNoAlias.forEach(k => {
if (!this._request.has(k)) {
throw new Error(`The "${k}" param is required`);
}
});
}
}
}

module.exports = OrderValid;
16 changes: 16 additions & 0 deletions lib/directlink/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Licensed under the MIT License
*
* @author Kanstantsin A Kamkou (2ka.by)
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
* @link https://github.com/kkamkou/node-concardis
*/

'use strict';

/* istanbul ignore next */
const path = require('path');

/* istanbul ignore next */
['Order', 'OrderSmart', 'OrderValid']
.forEach(c => module.exports[c] = require(path.join(__dirname, c)));
24 changes: 4 additions & 20 deletions lib/hosted/Url.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,13 @@ const QueryCollection = require('../request/Collection');
if (!(collection instanceof QueryCollection)) {
throw new TypeError('Query "Collection" expected');
}
this.endpoint = '' + endpoint;
this.collection = collection;
this._endpoint = '' + endpoint;
this._collection = collection;
}

toString() {
const requiredOneOf = ['CARD.BRAND', 'CARD.PAYMENTMETHOD'],
required = [
'ACCOUNT.PSPID', 'PARAMETERS.ACCEPTURL', 'PARAMETERS.EXCEPTIONURL',
'SHASIGNATURE.SHASIGN'
];

required.forEach(k => {
if (!this.collection.has(k)) {
throw new Error(`The "${k}" param is required`);
}
});

if (requiredOneOf.filter(k => !this.collection.has(k)).length === requiredOneOf.length) {
throw new Error(`One of "${requiredOneOf.join(',')}" params is required`);
}

return [this.endpoint, this.collection.toUrn()].join('/?');
return [this._endpoint, this._collection.toUrn()].join('/?');
}
}

module.exports = Url;
module.exports = Url;
39 changes: 16 additions & 23 deletions lib/hosted/UrlSmart.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,23 @@
const CollectionChecksum = require('../request/CollectionChecksum'),
SignedCollection = require('../request/SignedCollection'),
ObjectCollection = require('../request/ObjectCollection'),
Url = require('./Url');
UrlValid = require('./UrlValid');

/*public final*/ class UrlSmart extends Url {
constructor(endpoint, checksum, collection) {
super(endpoint, new SignedCollection('shasignature.shasign', checksum, collection));
}

static test(secret, obj, algorithm) {
const collection = new ObjectCollection(obj);
return new this(
'https://payengine.test.v-psp.com/Tokenization/Hostedpage',
new CollectionChecksum(collection, secret, algorithm),
collection
);
}

static production(secret, obj, algorithm) {
const collection = new ObjectCollection(obj);
return new this(
'https://secure.payengine.de/Tokenization/HostedPage',
const instance = (endpoint, secret, obj, algorithm) => {
const collection = new ObjectCollection(obj);
return new UrlValid(
endpoint,
new SignedCollection(
'shasignature.shasign',
new CollectionChecksum(collection, secret, algorithm),
collection
);
}
}
)
);
};

module.exports = UrlSmart;
module.exports = {
test: (secret, obj, algorithm) =>
instance('https://payengine.test.v-psp.com/Tokenization/Hostedpage', secret, obj, algorithm),
production: (secret, obj, algorithm) =>
instance('https://secure.payengine.de/Tokenization/HostedPage', secret, obj, algorithm)
};
Loading

0 comments on commit d617ea3

Please sign in to comment.