Skip to content

Commit

Permalink
Adds RiskDataCollector component
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissrogers committed Apr 30, 2020
1 parent c126874 commit 4e6d85e
Show file tree
Hide file tree
Showing 8 changed files with 15,713 additions and 9,912 deletions.
37 changes: 37 additions & 0 deletions docs/1-components/RiskDataCollector.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Story, Subtitle, Props } from '@storybook/addon-docs/blocks';
import { propsSlotFor } from '../shared/prop-types';
import { RiskDataCollector } from '../../lib';

<Meta title="Components/RiskDataCollector"parameters={{ sortOrder: 6 }} />

# RiskDataCollector
<Subtitle slot={() => 'Fraud protection for your checkout'} />

`import { RiskDataCollector } from '@recurly/react-recurly';`

This component adds data collection elements to your checkout which are applied to any tokens generated within the bounds of its nearest ascendant parent `HTMLFormElement`.

This component is compatible with [Recurly Fraud Management][doc-recurly-fraud-management] and [Kount][doc-kount].

```js
import { RiskDataCollector } from '@recurly/react-recurly';

() => {
const handleError = (error) => {
// error.code
// error.message
};

return (
<RiskDataCollector
strategy="kount"
onError={handleError}
/>
);
};
```

<Props slot={propsSlotFor(RiskDataCollector, {})} />

[doc-recurly-fraud-management]: https://docs.recurly.com/docs/fraud-management
[doc-kount]: https://docs.recurly.com/docs/kount
4 changes: 2 additions & 2 deletions docs/1-components/ThreeDSecureAction.stories.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Story, Subtitle } from '@storybook/addon-docs/blocks';
import { Story, Subtitle, Props } from '@storybook/addon-docs/blocks';
import { propsSlotFor } from '../shared/prop-types';
import { ThreeDSecureAction } from '../../lib';

<Meta title="Components/ThreeDSecureAction"parameters={{ sortOrder: 6 }} />
<Meta title="Components/ThreeDSecureAction"parameters={{ sortOrder: 7 }} />

# ThreeDSecureAction
<Subtitle slot={() => 'Display a 3-D Secure authentication flow'} />
Expand Down
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import CardNumberElement from './element/card-number';
import CardMonthElement from './element/card-month';
import CardYearElement from './element/card-year';
import CardCvvElement from './element/card-cvv';
import RiskDataCollector from './risk-data-collector';
import ThreeDSecureAction from './three-d-secure-action';
import useCheckoutPricing from './use-checkout-pricing';

Expand All @@ -18,6 +19,7 @@ export {
CardMonthElement,
CardYearElement,
CardCvvElement,
RiskDataCollector,
ThreeDSecureAction,
useCheckoutPricing
};
86 changes: 86 additions & 0 deletions lib/risk-data-collector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React from 'react';
import PropTypes from 'prop-types';
import { RecurlyContext } from './provider';

export const RISK_STRATEGIES = ['kount'];

/**
* Injects risk data collection point in your checkout.
*
* <https://docs.recurly.com/docs/kount>
*/
export default class RiskDataCollector extends React.Component {
static propTypes = {
/**
* Applied to the container.
*/
id: PropTypes.string,

/**
* Applied to the container.
*/
className: PropTypes.string,

/**
* Risk data collection strategy.
*
* Possible values: 'kount'
*/
strategy: PropTypes.oneOf(RISK_STRATEGIES),

/**
* Called when an error is encountered
* @type {FraudDataCollector~onError}
*/

/**
* @callback FraudDataCollector~onError
* @param {RecurlyError}
*/
onError: PropTypes.func
};

static defaultProps = {
id: undefined,
className: undefined,
strategy: RISK_STRATEGIES[0],
onError: e => { throw e }
};

static contextType = RecurlyContext;

constructor (props, context) {
super(props, context);

if (!context || !context.recurly) {
throw new Error('<RiskDataCollector> must be within a <RecurlyProvider> tree.');
}

/**
* TODO
* Once recurly.Fraud is decommissioned in favor of recurly.Risk.FraudConcern,
* this will change to consume a RiskProvider.
*/
this._container = React.createRef();
this._recurly = this.context.recurly;
}

componentDidMount () {
const { _container: container, _recurly: recurly } = this;
const { strategy, onError } = this.props;

recurly.configure({ fraud: { [strategy]: { dataCollector: true, form: container } } });
const fraud = this._fraud = recurly.fraud;
fraud.on('error', (...args) => onError(...args));
}

render () {
return (
<div
id={this.props.id}
className={this.props.className}
ref={this._container}
/>
);
}
};
Loading

0 comments on commit 4e6d85e

Please sign in to comment.