Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Commit

Permalink
Merge e74cf1a into 23dde25
Browse files Browse the repository at this point in the history
  • Loading branch information
Dylan Lott authored Nov 15, 2017
2 parents 23dde25 + e74cf1a commit fb79c9e
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 5 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ db.models.User.findOne({ email: 'gordon@storj.io' }, function(err, user) {
});
```


#### Coinpayments Integration

You'll have to set Coinpayments environment variables `CP_PUBLIC_KEY` and `CP_SECRET_KEY` in order to get coinpayments client working with the payment processor adapter.



#### Billing Specific

If using billing functionality, be sure to include your own `.env` file with necessary environment variables.
1 change: 1 addition & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = {
STRIPE: 'stripe',
BRAINTREE: 'braintree',
HEROKU: 'heroku',
COINPAYMENTS: 'coinpayments',
DEFAULT: 'none'
},
STRIPE_MIN_CENTS: 1.0,
Expand Down
67 changes: 67 additions & 0 deletions lib/models/payment-processor-adapters/coinpayments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use strict';

const coinpayments = require('../../vendor/coinpayments');

let coinpaymentsProcessor;

const coinpaymentsAdapter = {

serializeData: function (data) {
return data;
},

parseData: function () {
return coinpaymentsProcessor.rawData;
},

addPaymentMethod: function (token) {
return new Promise((resolve, reject) => {
coinpayments.getCallbackAddress(token, function(err, data) {
if (err) {
reject(err);
}
coinpaymentsProcessor.data.push({
token: token,
address: data.address
});
return coinpaymentsProcessor.save()
.then(resolve)
.catch(reject);
});
});
},

removePaymentMethod: function (address) {
return new Promise((resolve, reject) => {
const updated = coinpaymentsProcessor.data.filter(item => {
return item.address !== address;
});
coinpaymentsProcessor.data = updated;
return coinpaymentsProcessor.save()
.then(resolve)
.catch(reject);
});
},

defaultPaymentMethod: function () {
return coinpaymentsProcessor.rawData;
},

validate: function () {
return Promise.resolve(true);
},

billingDate: function () {
return 1;
},

paymentMethods: function () {
return coinpaymentsProcessor.rawData;
}

};

module.exports = function(paymentProcessor) {
coinpaymentsProcessor = paymentProcessor;
return coinpaymentsAdapter;
};
6 changes: 3 additions & 3 deletions lib/models/payment-processor-adapters/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
const constants = require('../../constants');
const STRIPE = constants.PAYMENT_PROCESSORS.STRIPE;
const BRAINTREE = constants.PAYMENT_PROCESSORS.BRAINTREE;
// const HEROKU = constants.PAYMENT_PROCESSORS.HEROKU;
const COINPAYMENTS = constants.PAYMENT_PROCESSORS.COINPAYMENTS;

const stripeAdapter = require('./stripe');
const braintreeAdapter = require('./braintree');
//const herokuAdapter = require('./heroku');
const coinpaymentsAdapter = require('./coinpayments');

const adapters = {};
adapters[STRIPE] = stripeAdapter;
adapters[BRAINTREE] = braintreeAdapter;
//adapters[HEROKU] = herokuAdapter;
adapters[COINPAYMENTS] = coinpaymentsAdapter;

module.exports = adapters;
4 changes: 2 additions & 2 deletions lib/models/payment-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ PaymentProcessorSchema.virtual('billingDate').get(function() {

PaymentProcessorSchema.virtual('currentBillingPeriod').get(function() {
const referenceMoment = moment.utc();
return getBillingPeriodFor(referenceMoment, this.data.billingDate);
return getBillingPeriodFor(referenceMoment, this.adapter.billingDate());
});

PaymentProcessorSchema.virtual('nextBillingPeriod').get(function() {
const referenceMoment = moment.utc().add(1, 'month');
return getBillingPeriodFor(referenceMoment, this.data.billingDate);
return getBillingPeriodFor(referenceMoment, this.adapter.billingDate());
});

PaymentProcessorSchema.virtual('paymentMethods').get(function() {
Expand Down
22 changes: 22 additions & 0 deletions lib/vendor/coinpayments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const Coinpayments = require('coinpayments');

const options = {
key: process.env.CP_PUBLIC_KEY,
secret: process.env.CP_PRIVATE_KEY
};

let client;

try {
client = new Coinpayments(options);
} catch (err) {
if (err.message === 'Missing public key and/or secret') {
console.log(err.message);
return;
} else {
throw(err);
}
}


module.exports = client;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"homepage": "https://github.com/Storj/service-storage-models#readme",
"dependencies": {
"bluebird": "^3.4.7",
"coinpayments": "^1.1.2",
"dotenv": "^2.0.0",
"elliptic": "^6.3.2",
"hat": "0.0.3",
Expand Down
133 changes: 133 additions & 0 deletions test/payment-processor-adapters/coinpayments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
'use strict';

const expect = require('chai').expect;
const proxyquire = require('proxyquire');
const sinon = require('sinon');
const libPath = '../../lib/models/payment-processor-adapters/coinpayments';


describe('Storage/models/PaymentProcessor/coinpayments', function () {

describe('#addPaymentMethod', function () {
it('it should push data', function (done) {
const data = {
address: '0x703faaa2f42291e0aaa9ffdbd74ae81172895bc7'
};
const Adapter = proxyquire(libPath, {
'../../vendor/coinpayments': {
getCallbackAddress: sinon.stub().callsArgWith(1, null, data)
}
});
const paymentProcessor = {
data: [],
save: sinon.stub().returns(new Promise((resolve) => {
resolve();
}))
};
const adapter = Adapter(paymentProcessor);

const token = 'token';
adapter.addPaymentMethod(token).then(() => {
expect(paymentProcessor.data.length).to.equal(1);
expect(paymentProcessor.data[0]).to.eql({
token: 'token',
address: data.address
});
done();
});
});
it('it should handle error from save', function (done) {
const data = {
address: '0x703faaa2f42291e0aaa9ffdbd74ae81172895bc7'
};
const Adapter = proxyquire(libPath, {
'../../vendor/coinpayments': {
getCallbackAddress: sinon.stub().callsArgWith(1, null, data)
}
});
const paymentProcessor = {
data: [],
save: sinon.stub().returns(new Promise((resolve, reject) => {
reject(new Error('test'));
}))
};
const adapter = Adapter(paymentProcessor);

const token = 'token';
adapter.addPaymentMethod(token).catch((err) => {
expect(err.message).to.equal('test');
done();
});
});
});

describe('#removePaymentMethod', function () {
it('it should remove address', function (done) {
const data = {
address: '0x703faaa2f42291e0aaa9ffdbd74ae81172895bc7'
};
const Adapter = proxyquire(libPath, {
'../../vendor/coinpayments': {
getCallbackAddress: sinon.stub().callsArgWith(1, null, data)
}
});
const paymentProcessor = {
data: [{
address: '0xaaf71b381afd506107f17ed11d0fc793b2283fe7',
token: 'token2'
}, {
address: '0x2266e1d04bc51c72c682549c7f6c216883458362',
token: 'token3'
}],
save: sinon.stub().returns(new Promise((resolve) => {
resolve();
}))
};
const adapter = Adapter(paymentProcessor);
const token = 'token';

adapter.addPaymentMethod(token).then(() => {
expect(paymentProcessor.data.length).to.equal(3);
adapter.removePaymentMethod(data.address).then(() => {
expect(paymentProcessor.data.length).to.equal(2);
done();
});
});
});
it('it should handle error from save', function (done) {
const data = {
address: '0x703faaa2f42291e0aaa9ffdbd74ae81172895bc7'
};
const Adapter = proxyquire(libPath, {
'../../vendor/coinpayments': {
getCallbackAddress: sinon.stub().callsArgWith(1, null, data)
}
});
const paymentProcessor = {
data: [],
save: sinon.stub().returns(new Promise((resolve) => {
resolve();
}))
};
paymentProcessor.save.onSecondCall()
.returns(new Promise((resolve, reject) => {
reject(new Error('test'));
}));
const adapter = Adapter(paymentProcessor);
const token = 'token';

adapter.addPaymentMethod(token).then(() => {
expect(paymentProcessor.data.length).to.equal(1);
expect(paymentProcessor.data[0]).to.eql({
token: 'token',
address: data.address
});
adapter.removePaymentMethod(data.address).catch((err) => {
expect(err.message).to.equal('test');
done();
});
});
});
});

});

0 comments on commit fb79c9e

Please sign in to comment.