Skip to content

Instantly share code, notes, and snippets.

@iloveitaly
Last active October 17, 2019 20:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save iloveitaly/2589fa56516f892e69573af4f10acc49 to your computer and use it in GitHub Desktop.
Save iloveitaly/2589fa56516f892e69573af4f10acc49 to your computer and use it in GitHub Desktop.
Automate order approval in NetSuite using data from Stripe's fraud detection system using http://SuiteSync.io/
/*
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