From 705347137670dcbc65f70fa17fb6cc4fc5144fb7 Mon Sep 17 00:00:00 2001 From: gil Date: Thu, 12 Dec 2024 21:38:51 -0800 Subject: [PATCH] Pass billingAddress fields for Proactive 3DS --- lib/recurly/risk/risk.js | 4 +-- .../risk/three-d-secure/strategy/braintree.js | 7 +++-- .../risk/three-d-secure/three-d-secure.js | 4 +-- lib/recurly/token.js | 29 +++++++++++++++++-- .../three-d-secure/strategy/braintree.test.js | 21 +++++++++++--- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/lib/recurly/risk/risk.js b/lib/recurly/risk/risk.js index 91c744e2..f07c32a2 100644 --- a/lib/recurly/risk/risk.js +++ b/lib/recurly/risk/risk.js @@ -55,7 +55,7 @@ export class Risk { * @param {String} options.bin credit card BIN * @return {Promise} */ - static preflight ({ recurly, number, month, year, cvv }) { + static preflight ({ recurly, number, month, year, cvv, addressFields }) { const data = {}; if (recurly.config.risk.threeDSecure.proactive.enabled) { @@ -66,7 +66,7 @@ export class Risk { return recurly.request.get({ route: '/risk/preflights', data }) .then(({ preflights }) => { debug('received preflight instructions', preflights); - return ThreeDSecure.preflight({ recurly, number, month, year, cvv, preflights }); + return ThreeDSecure.preflight({ recurly, number, month, year, cvv, preflights, addressFields }); }) .then(({ tokenType, risk }) => ({ risk: risk.filter(maybeErr => { diff --git a/lib/recurly/risk/three-d-secure/strategy/braintree.js b/lib/recurly/risk/three-d-secure/strategy/braintree.js index 57f69f76..17dea24b 100644 --- a/lib/recurly/risk/three-d-secure/strategy/braintree.js +++ b/lib/recurly/risk/three-d-secure/strategy/braintree.js @@ -10,7 +10,7 @@ export default class BraintreeStrategy extends ThreeDSecureStrategy { return BraintreeLoader.loadModules('threeDSecure'); } - static preflight ({ recurly, number, month, year, cvv }) { + static preflight ({ recurly, number, month, year, cvv, addressFields }) { const { enabled, gatewayCode, amount, currency } = recurly.config.risk.threeDSecure.proactive; debug('performing preflight for', { gatewayCode }); @@ -22,11 +22,12 @@ export default class BraintreeStrategy extends ThreeDSecureStrategy { const data = { gateway_type: BraintreeStrategy.strategyName, gateway_code: gatewayCode, - currency: currency, + currency, number, month, year, - cvv + cvv, + ...addressFields }; // we don't really need to do anything once we get a response except 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 723ec754..babfb075 100644 --- a/lib/recurly/risk/three-d-secure/three-d-secure.js +++ b/lib/recurly/risk/three-d-secure/three-d-secure.js @@ -99,13 +99,13 @@ export class ThreeDSecure extends RiskConcern { * @param {Preflights} options.preflights * @return {Promise} */ - static preflight ({ recurly, number, month, year, cvv, preflights }) { + static preflight ({ recurly, number, month, year, cvv, preflights, addressFields }) { return preflights.reduce((preflight, result) => { return preflight.then((finishedPreflights) => { const { type: gatewayType } = result.gateway; const { gateway_code } = result.params; const strategy = ThreeDSecure.getStrategyForGatewayType(gatewayType); - return strategy.preflight({ recurly, number, month, year, cvv, ...result.params }) + return strategy.preflight({ recurly, number, month, year, cvv, addressFields, ...result.params }) .then((preflightResponse) => { if (!preflightResponse) return finishedPreflights; const { results, tokenType } = preflightResponse; diff --git a/lib/recurly/token.js b/lib/recurly/token.js index 6c1fa333..2f95982d 100644 --- a/lib/recurly/token.js +++ b/lib/recurly/token.js @@ -172,9 +172,34 @@ function token (customerData, bus, done) { })); } - const { number, month, year, cvv } = inputs; + const { + number, + month, + year, + cvv, + first_name, + last_name, + address1, + address2, + city, + country, + postal_code, + state + } = inputs; + + const addressFields = { + first_name, + last_name, + address1, + address2, + city, + country, + postal_code, + state, + }; + if (number && month && year) { - Risk.preflight({ recurly: this, number, month, year, cvv }) + Risk.preflight({ recurly: this, number, month, year, cvv, addressFields }) .then(({ risk, tokenType }) => { inputs.risk = risk; if (tokenType) inputs.type = tokenType; diff --git a/test/unit/risk/three-d-secure/strategy/braintree.test.js b/test/unit/risk/three-d-secure/strategy/braintree.test.js index b376e4af..6e18a5f5 100644 --- a/test/unit/risk/three-d-secure/strategy/braintree.test.js +++ b/test/unit/risk/three-d-secure/strategy/braintree.test.js @@ -128,6 +128,18 @@ describe('BraintreeStrategy', function () { this.month = '01'; this.year = '2023'; this.cvv = '737' + + this.addressFields = { + first_name: 'John', + last_name: 'Doe', + address1: '123 Main St', + address2: 'Suite 100', + city: 'San Francisco', + country: 'US', + postal_code: '94105', + state: 'CA', + } + recurly.config.risk.threeDSecure.proactive = { enabled: true, gatewayCode: 'test-gateway-code', @@ -142,10 +154,10 @@ describe('BraintreeStrategy', function () { }); it('sends the correct data', function (done) { - const { recurly, number, month, year, cvv } = this; + const { recurly, number, month, year, cvv, addressFields } = this; - BraintreeStrategy.preflight({ recurly, number, month, year, cvv }).then(() => { - sinon.assert.calledWithMatch(recurly.request.post, { + BraintreeStrategy.preflight({ recurly, number, month, year, cvv, addressFields }).then(() => { + sinon.assert.calledWithExactly(recurly.request.post, { route: '/risk/authentications', data: { gateway_type: BraintreeStrategy.strategyName, @@ -154,7 +166,8 @@ describe('BraintreeStrategy', function () { number, month, year, - cvv + cvv, + ...addressFields } }); done();