Automate order approval in NetSuite using data from Stripe's fraud detection system using http://SuiteSync.io/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Author: <mike@suitesync.io> | |
Description: Detects if a transaction is marked as fraudulent/safe by Stripe's fraud system | |
https://dashboard.suitesync.io/docs/fraud-prevention | |
Installation: | |
1. https://system.sandbox.netsuite.com/app/common/scripting/uploadScriptFile.nl | |
2. User Event | |
3. Name: Stripe Fraud Handler | |
4. ID: _stripe_fraud_handler | |
5. After Submit: afterSubmit | |
6. Deployments: SalesOrder, Invoice, CashSale (depending on your NetSuite usage) | |
*/ | |
// Pulled from utilities | |
// https://gist.github.com/iloveitaly/db7d532e772b67f5b81d0199d094301f | |
function log(msg) { | |
nlapiLogExecution('DEBUG', msg); | |
} | |
function isEmpty(obj) { | |
return obj === undefined || obj === null || obj === ""; | |
} | |
function startsWith(str, searchString) { | |
return str.indexOf(searchString) === 0; | |
} | |
// Don't ask why SuiteScript uses 'A' and 'B' to represent the `orderstatus` | |
var NETSUITE_SALES_ORDER_PENDING_APPROVAL_STATUS = 'A'; | |
var NETSUITE_SALES_ORDER_APPROVED_STATUS = 'B'; | |
var NETSUITE_INVOICE_APPROVED_STATUS = '2'; | |
// NOTE the wrapper function `processAfterSubmit` is used to enable the logic to be | |
// easily reused in other contexts (i.e. debugging, mass update, etc) | |
function afterSubmit() { | |
var recordType = nlapiGetRecordType(); | |
var recordId = nlapiGetRecordId(); | |
processAfterSubmit(recordType, recordId); | |
} | |
function processAfterSubmit(type, internalId) { | |
var isFraudProcessed = nlapiLookupField(type, internalId, 'custbody_suitesync_fraud_processed', false); | |
if(isFraudProcessed == 'T') { | |
if(isEmpty(nlapiLookupField(type, internalId, 'custbody_suitesync_fraud_message', false))) { | |
transactionIsSafe(type, internalId); | |
} else { | |
transactionIsFraudulent(type, internalId); | |
} | |
} else { | |
log("transaction not processed for fraud"); | |
} | |
} | |
function transactionIsFraudulent(recordType, internalId) { | |
log("transaction is fradulent"); | |
var fraudMessage = nlapiLookupField(recordType, internalId, 'custbody_suitesync_fraud_message', false); | |
// NOTE startsWith is used to prevent message detection from breaking when whitespace, punctuation, etc | |
// is added to the fraud message. Note that this is a custom method that is included at the top of this script. | |
// NOTE you may not want to change how you handle fraudulent transactions based on the fraud message. | |
// this logic is provided here as an example in case you need this functionality. | |
if(startsWith(fraudMessage, 'One of your rules placed this charge in manual review')) { | |
} else if(startsWith(fraudMessage, 'Marked as risky by Stripe')) { | |
} else { | |
// additional fraud messages may be added in the future, ensure that all fraud messages are handled | |
} | |
// NOTE exactly what you do when a transaction is fraudulent is highly dependent on your specific | |
// NetSuite environment. Below are some examples of what you could do. | |
// NOTE that setting status and statusRef don't do anything, although they won't fail. | |
// the orderstatus (NOT orderStatus) is the only field that will change the status. | |
// NOTE pro-tip: use `nlapiGetFieldValue('orderstatus')` in the browser console when you have a transaction | |
// in edit mode to pull the value that NetSuite expects in SuiteScript. | |
if(recordType == 'salesorder') { | |
nlapiSubmitField(recordType, internalId, 'orderStatus', NETSUITE_SALES_ORDER_PENDING_APPROVAL_STATUS); | |
} else if(type == 'invoice') { | |
// NOTE that invoices cannot be moved from Approved => Pending Approval | |
} else if(type == 'cashsale') { | |
} | |
} | |
function transactionIsSafe(recordType, internalId) { | |
log("transaction is safe"); | |
// NOTE exactly what you do when a transaction is safe is highly dependent on your specific | |
// NetSuite environment. Below are some examples of what you could do. | |
if(recordType == 'salesorder') { | |
nlapiSubmitField(recordType, internalId, 'orderstatus', NETSUITE_SALES_ORDER_APPROVED_STATUS); | |
} else if(type == 'invoice') { | |
nlapiSubmitField(recordType, internalId, 'approvalstatus', NETSUITE_INVOICE_APPROVED_STATUS); | |
} else if(type == 'cashsale') { | |
} | |
} | |
// this condition enables us to run this script and the debugger to test with | |
// a specific transaction in NetSuite. This is helpful for script debugging/editing | |
if(nlapiGetContext().getExecutionContext() == 'debugger') { | |
processAfterSubmit('salesorder', 8931604); | |
} | |
// allows you set a breakpoint at the end of the script | |
'debug'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment