Package Exports
- yield-siftscience
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (yield-siftscience) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Yield Sift Science - NodeJS
A promise-wrapped helper lib for yielding Sift Science API calls in nodejs.
Also supports regular callbacks.
Table of contents:
- Installation
- Usage
- Events API
- Labels API
- Decision API
- Workflow API
- Score API
- Device Fingerprinting API
- Partner API
- Callbacks
- Constants
- Webhooks
- Sift Science Documentation
- Testing
- Change Log
INSTALLATION
Using npm:
$ npm install yield-siftscienceUSAGE
Require with API Key:
var siftscience = require('yield-siftscience')({
api_key: 'YOUR_SIFT_SCIENCE_REST_API_KEY'
});Available Options:
- {string} api_key (get your api key)
- {string} [account_id] (required for device fingerprinting api, get your account id)
- {string} [partner_id] (required for partner api, get your partner id)
- {string[]} [custom_events] (ex:
['referral_code_redeemed', 'contacted_customer_support', ...]) - {function} [global_callback] (ex:
function(err, response) { ... }- can be used to override promise and make regular callback on all requests) - {string[]} [abuse_types] (default:
[]- specify an array of sift science products. This parameter restricts the list of score or workflow decision retrieved to the specific products requested. more info. Possible values: Array with one or more of -['payment_abuse','promo_abuse','content_abuse','account_abuse','legacy']) - {boolean} [return_score] (default:
false- can be used to return score from sift science synchronously more info) - {boolean} [return_workflow_status] (default:
false- can be used to return workflow status from sift science synchronously more info) - {object} [webhooks] (default:
{}- see webhooks for usage) - {boolean} [return_action] DEPRECATED (default:
false- can be used to get extra params from sift science responses more info)
Note: In v204 of the sift science API, return_action is deprecated in favor of the more granular combined use of abuse_types, return_score and return_workflow_status flags. more info
EVENTS API
https://siftscience.com/developers/docs/curl/events-api
Send Event:
var result = yield siftscience.event.create_account({
'$session_id': session.id,
'$user_id': user.id,
'$user_email': user.email
});var result = yield siftscience.event.login({
'$session_id': session.id,
'$user_id': user.id,
'$login_status': siftscience.CONSTANTS.STATUS.SUCCESS
});Send Generic Custom Event:
var result = yield siftscience.event.custom_event('referral_code_redeemed', {
'$session_id': session.id,
'$user_id': user.id,
'code': 'abc123'
});var result = yield siftscience.event.custom_event('contacted_customer_support', {
'$session_id': session.id,
'$user_id': user.id
});Inject Custom Events:
Optionally, you can pass in an array of custom event names to add to the lib
var siftscience = require('yield-siftscience')({
api_key: 'YOUR_SIFT_SCIENCE_REST_API_KEY',
custom_events: ['referral_code_redeemed', 'contacted_customer_support', ...]
});Then you could use
var result = yield siftscience.event.referral_code_redeemed({
'$session_id': session.id,
'$user_id': user.id,
'code': 'abc123'
});var result = yield siftscience.event.contacted_customer_support({
'$session_id': session.id,
'$user_id': user.id,
});LABELS API
https://siftscience.com/developers/docs/curl/labels-api
Send Label:
var result = yield siftscience.label(user.id, {
'$is_bad': true,
'$abuse_type': siftscience.CONSTANTS.ABUSE_TYPE.PAYMENT_ABUSE,
'$description': 'Because they are spamming and abusing our system',
'$source': 'manual review',
'$analyst': 'admin@example.com'
});Remove Label:
var result = yield siftscience.unlabel(user.id);DECISION API
https://siftscience.com/developers/docs/curl/decisions-api
Get decision status:
var result = yield siftscience.decision.status(siftscience.CONSTANTS.ENTITY_TYPE.USERS, entity.id)List decisions:
var result = yield siftscience.decision.list(siftscience.CONSTANTS.ENTITY_TYPE.USER)Apply decision to user:
var result = yield siftscience.decision.apply(user.id, null, {
'decision_id': 'user_looks_ok_payment_abuse',
'source': siftscience.CONSTANTS.DECISION_SOURCE.MANUAL_REVIEW,
'analyst': 'analyst@email.com',
'description': 'applied via the high priority queue, queued user because their risk score exceeded 85'
})Apply decision to order:
var result = yield siftscience.decision.apply(user.id, order.id, {
'decision_id': 'user_looks_ok_payment_abuse',
'source': siftscience.CONSTANTS.DECISION_SOURCE.AUTOMATED_RULE,
'description': 'Auto block pending order as score exceeded risk threshold of 90'
})WORKFLOW API
https://siftscience.com/developers/docs/curl/workflows-api
Get workflow status:
var result = yield siftscience.workflow.status(workflow.id)SCORE API
https://siftscience.com/developers/docs/curl/score-api
Get Score:
var result = yield siftscience.score(user.id);DEVICE FINGERPRINTING API
https://siftscience.com/developers/docs/curl/device-fingerprinting-api
JavaScript Snippet:
https://siftscience.com/developers/docs/javascript/javascript-api
Install the following JavaScript snippet on every public-facing page on your site. Do not include this snippet on internal tools or administration systems.
Replace 'UNIQUE_SESSION_ID', 'UNIQUE_USER_ID', and 'INSERT_JS_SNIPPET_KEY_HERE' with proper values
<script type="text/javascript">
var _user_id = 'UNIQUE_USER_ID';
var _session_id = 'UNIQUE_SESSION_ID';
var _sift = window._sift = window._sift || [];
_sift.push(['_setAccount', 'INSERT_JS_SNIPPET_KEY_HERE']);
_sift.push(['_setUserId', _user_id]);
_sift.push(['_setSessionId', _session_id]);
_sift.push(['_trackPageview']);
(function() {
function ls() {
var e = document.createElement('script');
e.src = 'https://cdn.siftscience.com/s.js';
document.body.appendChild(e);
}
if (window.attachEvent) {
window.attachEvent('onload', ls);
} else {
window.addEventListener('load', ls, false);
}
})();
</script>Init with Account ID:
An Account ID is required to use the fingerprint api. Get your Account ID
var siftscience = require('yield-siftscience')({
api_key: 'YOUR_SIFT_SCIENCE_REST_API_KEY',
account_id: 'YOUR_SIFT_SCIENCE_ACCOUNT_ID'
});Get Session:
var result = yield siftscience.fingerprint.get_session(session.id);Get Device:
var result = yield siftscience.fingerprint.get_device(device_fingerprint);Label Device:
var result = yield siftscience.fingerprint.label_device(device_fingerprint, siftscience.CONSTANTS.DEVICE_LABEL.BAD);Get Devices:
var result = yield siftscience.fingerprint.get_devices(user.id);PARTNER API
https://siftscience.com/developers/docs/curl/partner-api
NOTE: I have not tested these as I do not have a partner account with sift science. Please report any bugs.
Init with Account ID and Partner ID (they may be the same thing, I'm not sure):
An Account & Partner ID are required to use the partner api. Get your Account & Partner ID
var siftscience = require('yield-siftscience')({
api_key: 'YOUR_SIFT_SCIENCE_REST_API_KEY',
account_id: 'YOUR_SIFT_SCIENCE_ACCOUNT_ID',
partner_id: 'YOUR_SIFT_SCIENCE_PARTNER_ID'
});Create Account:
var result = yield siftscience.partner.create_account({
site_url: 'merchant123.com',
site_email: 'owner@merchant123.com',
analyst_email: 'john.doe@merchant123.com',
password: 's0mepA55word'
});List Accounts:
var result = yield siftscience.partner.list_accounts();Configure Notifications:
var result = yield siftscience.partner.configure_notifications({
email_notification_threshold: 0.5,
http_notification_threshold: 0.5,
http_notification_url: 'https://api.partner.com/notify?account=%s'
});CALLBACKS
Don't know what yielding or promising is? All calls support regular callbacks:
siftscience.score(user.id, function(_err, _response) {
if (_err) {
console.log(_err);
}
else {
var score = _response.body;
console.log(score);
}
});You can also inject a global callback for all requests:
var siftscience = require('yield-siftscience')({
api_key: 'YOUR_SIFT_SCIENCE_REST_API_KEY',
global_callback: function(_err, _response) {
if (_err) {
console.log(_err);
}
else {
var result = _response.body;
console.log(result);
}
}
});CONSTANTS
siftscience.CONSTANTS = {
SHIPPING_METHOD: {
ELECTRONIC: '$electronic',
PHYSICAL: '$physical'
},
TRANSACTION_TYPE: {
SALE: '$sale',
AUTHORIZE: '$authorize',
CAPTURE: '$capture',
VOID: '$void',
REFUND: '$refund',
DEPOSIT: '$deposit',
WITHDRAWAL: '$withdrawal',
TRANSFER: '$transfer'
},
STATUS: {
SUCCESS: '$success',
FAILURE: '$failure',
PENDING: '$pending'
},
FAILURE_REASON: {
ALREADY_USED: '$already_used',
INVALID_CODE: '$invalid_code',
NOT_APPLICABLE: '$not_applicable',
EXPIRED: '$expired'
},
SOCIAL_SIGN_ON_TYPE: {
FACEBOOK: '$facebook',
GOOGLE: '$google',
YAHOO: '$yahoo',
TWITTER: '$twitter',
OTHER: '$other',
LINKEDIN: '$linkedin'
},
CONTENT_STATUS: {
DRAFT: '$draft',
PENDING: '$pending',
ACTIVE: '$active',
PAUSED: '$paused',
DELETED_BY_USER: '$deleted_by_user',
DELETED_BY_COMPANY: '$deleted_by_company'
},
CHARGEBACK_STATE: {
RECEIVED: '$received',
ACCEPTED: '$accepted',
DISPUTED: '$disputed',
WON: '$won',
LOST: '$lost'
},
CHARGEBACK_REASON: {
FRAUD: '$fraud',
DUPLICATE: '$duplicate',
PRODUCT_NOT_RECEIVED: '$product_not_received',
PRODUCT_UNACCEPTABLE: '$product_unacceptable',
OTHER: '$other'
},
ORDER_STATUS: {
APPROVED: '$approved',
CANCELED: '$canceled',
HELD: '$held',
FULFILLED: '$fulfilled',
RETURNED: '$returned'
},
ORDER_CANCEL_REASON: {
PAYMENT_RISK: '$payment_risk',
ABUSE: '$abuse',
POLICY: '$policy',
OTHER: '$other'
},
ORDER_STATUS_SOURCE: {
AUTOMATED: '$automated',
MANUAL_REVIEW: '$manual_review'
},
VERIFICATION_TYPE: {
SMS: '$sms',
PHONE_CALL: '$phone_call',
EMAIL: '$email',
APP_TFA: '$app_tfa',
CAPTCHA: '$captcha'
},
PAYMENT_TYPE: {
CASH: '$cash',
CHECK: '$check',
CREDIT_CARD: '$credit_card',
CRYPTO_CURRENCY: '$crypto_currency',
DIGITAL_WALLET: '$digital_wallet',
ELECTRONIC_FUND_TRANSFER: '$electronic_fund_transfer',
FINANCING: '$financing',
GIFT_CARD: '$gift_card',
INTERAC: '$interac', // Deprecated?
INVOICE: '$invoice',
MONEY_ORDER: '$money_order',
MASTERPASS: '$masterpass', // Deprecated?
POINTS: '$points',
STORE_CREDIT: '$store_credit',
THIRD_PARTY_PROCESSOR: '$third_party_processor',
VOUCHER: '$voucher'
},
RESPONSE_STATUS_MESSAGE: {
'-4': 'Service currently unavailable. Please try again later.',
'-3': 'Server-side timeout processing request. Please try again later.',
'-2': 'Unexpected server-side error',
'-1': 'Unexpected server-side error',
'0': 'Success',
'51': 'Invalid API key',
'52': 'Invalid characters in field name',
'53': 'Invalid characters in field value',
'54': 'Specified user_id has no scoreable events',
'55': 'Missing required field',
'56': 'Invalid JSON in request',
'57': 'Invalid HTTP body',
'60': 'Rate limited',
'104': 'Invalid API version',
'105': 'Not a valid reserved field',
'111': 'This feature is not enabled in your feature plan.'
},
REASON: {
CHARGEBACK: '$chargeback',
SPAM: '$spam',
FUNNELING: '$funneling',
FAKE: '$fake',
REFERRAL: '$referral',
DUPLICATE_ACCOUNT: '$duplicate_account'
},
DEVICE_LABEL: {
BAD: 'bad',
NOT_BAD: 'not_bad'
},
DEVICE_PERVASIVENESS: {
LOW: 'low',
MEDIUM: 'medium',
HIGH: 'high'
},
ABUSE_TYPE: {
PAYMENT_ABUSE: 'payment_abuse',
CONTENT_ABUSE: 'content_abuse',
PROMOTION_ABUSE: 'promotion_abuse',
PROMO_ABUSE: 'promo_abuse',
ACCOUNT_ABUSE: 'account_abuse',
LEGACY: 'legacy'
},
DECISION: {
PAYMENT_ABUSE: 'payment_abuse',
PROMOTION_ABUSE: 'promotion_abuse',
PROMO_ABUSE: 'promo_abuse',
CONTENT_ABUSE: 'content_abuse',
ACCOUNT_ABUSE: 'account_abuse',
LEGACY: 'legacy'
},
DECISION_CATEGORY: {
BLOCK: 'BLOCK',
WATCH: 'WATCH',
ACCEPT: 'ACCEPT'
},
DECISION_SOURCE: {
MANUAL_REVIEW: 'MANUAL_REVIEW',
AUTOMATED_RULE: 'AUTOMATED_RULE',
CHARGEBACK: 'CHARGEBACK'
},
STATE: {
RUNNING: 'running',
FINISHED: 'finished',
FAILED: 'failed'
},
ENTITY_TYPE: {
USERS: 'users',
ORDERS: 'orders',
USER: 'user',
ORDER: 'order'
},
APP: {
DECISION: 'decision',
REVIEW_QUEUE: 'review_queue',
USER_SCORER: 'user_scorer',
ORDER_SCORER: 'order_scorer',
EVENT_PROCESSOR: 'event_processor'
},
ACCOUNT_STATE: {
ACTIVE: 'ACTIVE',
DISABLED: 'DISABLED',
DELETED: 'DELETED'
}
};WEBHOOKS
NOTE: Currently only supports express/body-parser
Install Express/Body-Parser:
$ npm install --save express
$ npm install --save body-parser
$ npm install --save yield-siftscienceExample App:
Let's say you have created an action called "Test" with Action ID test
var express = require('express');
var bodyParser = require('body-parser');
// Require yield-siftscience with a webhooks mapping option
var siftscience = require('yield-siftscience')({
api_key: 'YOUR_SIFT_SCIENCE_REST_API_KEY',
webhooks: {
// This will receive all webhooks, regardless of Action ID
all: function(req, res, done) {
console.log('all: ', req.body);
done();
},
// This will receive webhooks with Action ID 'test'
test: function(req, res, done) {
console.log('test: ', req.body);
done();
}
}
});
// Set up the webhook listener
var app = express();
app.post('/siftscience', bodyParser.json(), siftscience.webhook.express());
app.listen(config.port);SIFT SCIENCE DOCUMENTATION
https://siftscience.com/developers/docs/curl/apis-overview
TESTING
Copy Example Config:
$ cp test/config-example.js test/config.js
$ nano test/config.jsSet Sandbox API Key, JS Key, Account ID, Workflow Run ID
module.exports = {
api_key: 'xxxxxxxxxxxxxxxx',
js_key: 'xxxxxxxxxx',
account_id: 'xxxxxxxxxxxxxxxxxxxxxxxx',
workflow_run_id: 'xxxxxxxxxxxxx',
host: 'localhost',
port: 3000
};Install Dependencies:
$ npm installRun Test:
$ npm testVisit Page:
Visiting the test web page will trigger a page view for user_id = '1' and session_id = '1'
http://localhost:3000NOTE: You will have to run the test a second time if this is your first time visiting the test web page
CHANGE LOG
0.2.1:
- Add support for decision list api
- Add support for apply decision api
- Add many missing
CONSTANTS - Add
$verificationevent
0.2.0:
- Update to API v204
- BREAKING CHANGE:
siftscience.unlabel()function signature has changed to support abuse type - BREAKING CHANGE:
siftscience.score()function signature has changed to support abuse types - Add support for decision status api
- Add support for workflow status api
0.1.2:
- Add validations for all arguments
- Update readme with more links to source reference
0.1.1:
- Found the
return_actiondocumentation - MORE INFO - Remove support for api version option - will only be supporting the most current version
v203 - Add validations for all init options
0.1.0:
- BREAKING CHANGE: Consolidate init args into one
optionsarg - see USAGE - Add support for
return_actionin init options - MORE INFO - Add support for device fingerprinting api
- Add support for partner api - NOTE: I do not have a partner account with sift science, this is untested. Please report any bugs.
- Add
CONSTANTSobject tosiftscienceobject for things like$reasonsand$shipping_method- see LABELS API - Add express/body-parser webhook support
- Add a minimal test package
0.0.9:
- Add
unlabelmethod tosiftscienceobject