diff --git a/lib/recurly/risk/risk.js b/lib/recurly/risk/risk.js index 54078c2b..a2126d3c 100644 --- a/lib/recurly/risk/risk.js +++ b/lib/recurly/risk/risk.js @@ -55,11 +55,11 @@ export class Risk { * @param {String} options.bin credit card BIN * @return {Promise} */ - static preflight ({ recurly, number, month, year }) { + static preflight ({ recurly, number, month, year, cvv }) { return recurly.request.get({ route: '/risk/preflights' }) .then(({ preflights }) => { debug('received preflight instructions', preflights); - return ThreeDSecure.preflight({ recurly, number, month, year, preflights }); + return ThreeDSecure.preflight({ recurly, number, month, year, cvv, preflights }); }) .then(results => results.filter(maybeErr => { if (maybeErr.code === 'risk-preflight-timeout') { diff --git a/lib/recurly/risk/three-d-secure/strategy/braintree.js b/lib/recurly/risk/three-d-secure/strategy/braintree.js index 4611c3fe..832544e5 100644 --- a/lib/recurly/risk/three-d-secure/strategy/braintree.js +++ b/lib/recurly/risk/three-d-secure/strategy/braintree.js @@ -6,9 +6,35 @@ import { BRAINTREE_CLIENT_VERSION } from '../../../../const/gateway-constants'; const debug = require('debug')('recurly:risk:three-d-secure:braintree'); export default class BraintreeStrategy extends ThreeDSecureStrategy { - static strategyName = 'braintree_blue'; + static preflight ({ recurly, number, month, year, cvv }) { + const { proactive } = recurly.config.risk.threeDSecure; + + if(!proactive.enabled) { + return Promise.resolve(); + } + + const { PREFLIGHT_TIMEOUT } = BraintreeStrategy; + const data = { + gatewayType: BraintreeStrategy.strategyName, + gatewayCode: proactive.gateway_code, + number, + month, + year, + cvv, + }; + + // we don't really need to do anything once we get a response except resolve with relevant data instead of session_id + return recurly.request.post({ route: '/risk/authentications', data }) + .then(({ paymentMethodNonce, clientToken, bin }) => ({ + payment_method_nonce: paymentMethodNonce, + client_token: clientToken, + bin + })); + } + + constructor (...args) { super(...args); diff --git a/lib/recurly/risk/three-d-secure/three-d-secure.js b/lib/recurly/risk/three-d-secure/three-d-secure.js index c847d782..5e1b28e5 100644 --- a/lib/recurly/risk/three-d-secure/three-d-secure.js +++ b/lib/recurly/risk/three-d-secure/three-d-secure.js @@ -94,13 +94,13 @@ export class ThreeDSecure extends RiskConcern { * @param {Preflights} options.preflights * @return {Promise} */ - static preflight ({ recurly, number, month, year, preflights }) { + static preflight ({ recurly, number, month, year, cvv, preflights }) { return preflights.reduce((preflight, result) => { return preflight.then((finishedPreflights) => { const { type } = result.gateway; const { gateway_code } = result.params; const strategy = ThreeDSecure.getStrategyForGatewayType(type); - return strategy.preflight({ recurly, number, month, year, ...result.params }) + return strategy.preflight({ recurly, number, month, year, cvv, ...result.params }) .then(results => { return finishedPreflights.concat([{ processor: type, gateway_code, results }]); }); diff --git a/lib/recurly/token.js b/lib/recurly/token.js index c387a7bf..d08e48d3 100644 --- a/lib/recurly/token.js +++ b/lib/recurly/token.js @@ -172,11 +172,10 @@ function token (customerData, bus, done) { })); } - const { number, month, year } = inputs; - Risk.preflight({ recurly: this, number, month, year }) + const { number, month, year, cvv } = inputs; + Risk.preflight({ recurly: this, number, month, year, cvv }) .then(results => { - inputs.risk = results - inputs.proactive = this.config.risk.threeDSecure.proactive + enrichInputs(this, inputs, results) }) .then(() => this.request.post({ route: '/tokens', data: inputs, done: complete })) .done(); @@ -189,4 +188,19 @@ function token (customerData, bus, done) { } done(null, res); } + + function enrichInputs(recurly, inputs, results) { + if (results.length === 0) return; + + inputs.risk = [] + + results.forEach(result => { + if (result.processor === 'braintree_blue') { + inputs.proactive = recurly.config.risk.threeDSecure.proactive; + inputs.proactive.params = result; + } else { + inputs.risk.push(result); + } + }) + } }