Merge pull request #7096 from piousbox/v3-payments-5

V3 payments 5
This commit is contained in:
Sabe Jones
2016-04-21 14:45:41 -05:00
7 changed files with 201 additions and 89 deletions
+2 -1
View File
@@ -173,5 +173,6 @@
"equipmentAlreadyOwned": "You already own that piece of equipment",
"missingAccessToken": "The request is missing a required parameter : access_token",
"missingBillingAgreementId": "Missing billing agreement id",
"missingAttributesFromAmazon": "Missing attributes from Amazon"
"missingAttributesFromAmazon": "Missing attributes from Amazon",
"paymentNotSuccessful": "The payment was not successful"
}
@@ -11,7 +11,7 @@ describe('payments : amazon', () => {
user = await generateUser();
});
it('verify access token', async () => {
it('verifies access token', async () => {
await expect(user.post(endpoint)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
+58 -4
View File
@@ -1,6 +1,7 @@
import * as amz from '../../../../../website/src/libs/api-v3/amazonPayments';
import * as amzLib from '../../../../../website/src/libs/api-v3/amazonPayments';
// import * as amzStub from 'amazon-payments';
import amazonPayments from 'amazon-payments';
var User = require('mongoose').model('User');
describe('amazonPayments', () => {
beforeEach(() => {
@@ -25,7 +26,7 @@ describe('amazonPayments', () => {
});
it('returns tokenInfo', async (done) => {
let result = await amz.getTokenInfo();
let result = await amzLib.getTokenInfo();
expect(result).to.eql(thisToken);
done();
});
@@ -34,7 +35,7 @@ describe('amazonPayments', () => {
describe('#getTokenInfo', () => {
it('validates access_token parameter', async (done) => {
try {
await amz.getTokenInfo();
await amzLib.getTokenInfo();
} catch (e) {
expect(e.type).to.eql('invalid_request');
done();
@@ -43,7 +44,60 @@ describe('amazonPayments', () => {
});
describe('#createOrderReferenceId', () => {
it('succeeds', () => {
it('verifies billingAgreementId', async (done) => {
try {
let inputSet = {};
delete inputSet.Id;
await amzLib.createOrderReferenceId(inputSet);
} catch (e) {
/* console.log('error!', e);
console.log('error keys!', Object.keys(e));
for (var key in e) {
console.log(e[key]);
} // */
expect(e.type).to.eql('InvalidParameterValue');
expect(e.body.ErrorResponse.Error.Message).to.eql('Parameter AWSAccessKeyId cannot be empty.');
done();
}
});
xit('succeeds', () => {
});
});
describe('#checkout', () => {
xit('succeeds');
});
describe('#setOrderReferenceDetails', () => {
xit('succeeds');
});
describe('#confirmOrderReference', () => {
xit('succeeds');
});
describe('#authorize', () => {
xit('succeeds');
xit('was declined');
xit('had an error');
});
describe('#closeOrderReference', () => {
xit('succeeds');
});
describe.only('#executePayment', () => {
it('succeeds not as a gift', () => {
});
it('succeeds as a gift', () => {
});
});
});
@@ -0,0 +1,11 @@
describe('payments/index', () => {
beforeEach(() => {
});
describe('#createSubscription', async () => {
});
describe('#buyGems', async () => {
});
});
@@ -10,7 +10,9 @@ import {
// NotAuthorized,
BadRequest,
} from '../../../libs/api-v3/errors';
import amz from '../../../libs/api-v3/amazonPayments';
import amzLib from '../../../libs/api-v3/amazonPayments';
import { authWithHeaders } from '../../../middlewares/api-v3/auth';
var payments = require('./index');
let api = {};
@@ -26,7 +28,7 @@ api.verifyAccessToken = {
method: 'POST',
url: '/payments/amazon/verifyAccessToken',
async handler (req, res) {
await amz.getTokenInfo(req.body.access_token)
await amzLib.getTokenInfo(req.body.access_token)
.then(() => {
res.respond(200, {});
}).catch((error) => {
@@ -46,47 +48,59 @@ api.verifyAccessToken = {
api.createOrderReferenceId = {
method: 'POST',
url: '/payments/amazon/createOrderReferenceId',
// middlewares: [authWithHeaders()],
async handler (req, res) {
if (!req.body.billingAgreementId) {
throw new BadRequest(res.t('missingBillingAgreementId'));
}
let response = await amz.createOrderReferenceId({
Id: req.body.billingAgreementId,
IdType: 'BillingAgreement',
ConfirmNow: false,
}).then(() => {
try {
let response = await amzLib.createOrderReferenceId({
Id: req.body.billingAgreementId,
IdType: 'BillingAgreement',
ConfirmNow: false,
AWSAccessKeyId: 'something',
});
res.respond(200, {
orderReferenceId: response.OrderReferenceDetails.AmazonOrderReferenceId,
});
}).catch(errStr => {
throw new BadRequest(res.t(errStr));
});
} catch (error) {
throw new BadRequest(error);
}
},
};
/*
api.checkout = function checkout (req, res, next) {
if (!req.body || !req.body.orderReferenceId) {
return res.status(400).json({err: 'Billing Agreement Id not supplied.'});
}
/**
* @api {post} /api/v3/payments/amazon/checkout do checkout
* @apiVersion 3.0.0
* @apiName AmazonCheckout
* @apiGroup Payments
*
* @apiParam {string} billingAgreementId billing agreement id
* @apiSuccess {object} object containing { orderReferenceId }
**/
api.checkout = {
method: 'POST',
url: '/payments/amazon/checkout',
middlewares: [authWithHeaders()],
async handler (req, res) {
let gift = req.body.gift;
let user = res.locals.user;
let orderReferenceId = req.body.orderReferenceId;
let amount = 5;
let gift = req.body.gift;
let user = res.locals.user;
let orderReferenceId = req.body.orderReferenceId;
let amount = 5;
if (gift) {
if (gift.type === 'gems') {
amount = gift.gems.amount / 4;
} else if (gift.type === 'subscription') {
amount = shared.content.subscriptionBlocks[gift.subscription.key].price;
if (gift) {
if (gift.type === 'gems') {
amount = gift.gems.amount / 4;
} else if (gift.type === 'subscription') {
amount = shared.content.subscriptionBlocks[gift.subscription.key].price;
}
}
}
async.series({
setOrderReferenceDetails (cb) {
amzPayment.offAmazonPayments.setOrderReferenceDetails({
/* if (!req.body || !req.body.orderReferenceId) {
return res.status(400).json({err: 'Billing Agreement Id not supplied.'});
} */
try {
await amzLib.setOrderReferenceDetails({
AmazonOrderReferenceId: orderReferenceId,
OrderReferenceAttributes: {
OrderTotal: {
@@ -99,17 +113,11 @@ api.checkout = function checkout (req, res, next) {
StoreName: 'HabitRPG',
},
},
}, cb);
},
});
confirmOrderReference (cb) {
amzPayment.offAmazonPayments.confirmOrderReference({
AmazonOrderReferenceId: orderReferenceId,
}, cb);
},
await amzLib.confirmOrderReference({ AmazonOrderReferenceId: orderReferenceId });
authorize (cb) {
amzPayment.offAmazonPayments.authorize({
await amzLib.authorize({
AmazonOrderReferenceId: orderReferenceId,
AuthorizationReferenceId: shared.uuid().substring(0, 32),
AuthorizationAmount: {
@@ -119,50 +127,31 @@ api.checkout = function checkout (req, res, next) {
SellerAuthorizationNote: 'HabitRPG Payment',
TransactionTimeout: 0,
CaptureNow: true,
}, function checkAuthorizationStatus (err) {
if (err) return cb(err);
if (res.AuthorizationDetails.AuthorizationStatus.State === 'Declined') {
return cb(new Error('The payment was not successfull.'));
}
return cb();
});
},
closeOrderReference (cb) {
amzPayment.offAmazonPayments.closeOrderReference({
AmazonOrderReferenceId: orderReferenceId,
}, cb);
},
await amzLib.closeOrderReference({ AmazonOrderReferenceId: orderReferenceId });
executePayment (cb) {
async.waterfall([
function findUser (cb2) {
User.findById(gift ? gift.uuid : undefined, cb2);
},
function executeAmazonPayment (member, cb2) {
let data = {user, paymentMethod: 'Amazon Payments'};
let method = 'buyGems';
// execute payment
let giftUser = await User.findById(gift ? gift.uuid : undefined);
let data = { giftUser, paymentMethod: 'Amazon Payments' };
let method = 'buyGems';
if (gift) {
if (gift.type === 'subscription') method = 'createSubscription';
gift.member = giftUser;
data.gift = gift;
data.paymentMethod = 'Gift';
}
await payments[method](data);
if (gift) {
if (gift.type === 'subscription') method = 'createSubscription';
gift.member = member;
data.gift = gift;
data.paymentMethod = 'Gift';
}
payments[method](data, cb2);
},
], cb);
},
}, function result (err) {
if (err) return next(err);
res.sendStatus(200);
});
res.respond(200);
} catch(error) {
throw new BadRequest(error);
}
};
/*
api.subscribe = function subscribe (req, res, next) {
if (!req.body || !req.body.billingAgreementId) {
return res.status(400).json({err: 'Billing Agreement Id not supplied.'});
@@ -36,6 +36,9 @@ function revealMysteryItems (user) {
});
}
// @TODO: HEREHERE
api.createSubscription = async function createSubscription (data) {
}
api.createSubscription = function createSubscription (data, cb) {
let recipient = data.gift ? data.gift.member : data.user;
let plan = recipient.purchased.plan;
@@ -150,6 +153,9 @@ api.cancelSubscription = function cancelSubscription (data, cb) {
analytics.track('unsubscribe', analyticsData);
};
// @TODO: HEREHERE
api.buyGems = async function buyGems (data) {
};
api.buyGems = function buyGems (data, cb) {
let amt = data.amount || 5;
amt = data.gift ? data.gift.gems.amount / 4 : amt;
@@ -229,5 +235,4 @@ api.amazonSubscribeCancel = amazon.subscribeCancel;
api.iapAndroidVerify = iap.androidVerify;
api.iapIosVerify = iap.iosVerify;
// module.exports = api;
module.exports = {}; // @TODO HEREHERE
module.exports = api;
+54 -2
View File
@@ -1,6 +1,7 @@
import amazonPayments from 'amazon-payments';
import nconf from 'nconf';
import common from '../../../../common';
let t = common.i18n.t;
const IS_PROD = nconf.get('NODE_ENV') === 'production';
let api = {};
@@ -31,11 +32,62 @@ api.createOrderReferenceId = (inputSet) => {
amzPayment.offAmazonPayments.createOrderReferenceForId(inputSet, (err, response) => {
if (err) return reject(err);
if (!response.OrderReferenceDetails || !response.OrderReferenceDetails.AmazonOrderReferenceId) {
return reject('missingAttributesFromAmazon');
return reject(t('missingAttributesFromAmazon'));
}
return resolve(response);
});
});
};
api.setOrderReferenceDetails = (inputSet) => {
let amzPayment = connect(amazonPayments);
return new Promise((resolve, reject) => {
amzPayment.offAmazonPayments.setOrderReferenceDetails(inputSet, (err, response) => {
if (err) return reject(err);
return resolve(response);
});
});
};
api.confirmOrderReference = (inputSet) => {
let amzPayment = connect(amazonPayments);
return new Promise((resolve, reject) => {
amzPayment.offAmazonPayments.confirmOrderReference(inputSet, (err, response) => {
if (err) return reject(err);
return resolve(response);
});
});
};
api.authorize = (inputSet) => {
let amzPayment = connect(amazonPayments);
return new Promize((resolve, reject) => {
amzPayment.offAmazonPayments.authorize(inputSet, (err, response) => {
if (err) return reject(err);
if (response.AuthorizationDetails.AuthorizationStatus.State === 'Declined') return reject(t('paymentNotSuccessful'));
return resolve(response);
});
});
};
api.closeOrderReference = (inputSet) => {
let amzPayment = connect(amazonPayments);
return new Promize((resolve, reject) => {
amzPayment.offAmazonPayments.closeOrderReference(inputSet, (err, response) => {
if (err) return reject(err);
return resolve(response);
});
});
};
api.executePayment = (inputSet) => {
let amzPayment = connect(amazonPayments);
return new Promize((resolve, reject) => {
amzPayment.offAmazonPayments.closeOrderReference(inputSet, (err, response) => {
if (err) return reject(err);
return resolve(response);
});
});
};
module.exports = api;