Click HERE to see how Saviynt Intelligence is transforming the industry. |
on 08/30/2023 08:31 AM
The NetSuite application can be integrated with Saviynt using the generic SOAP connector. Below are the JSONS to make a successful connection with NetSuite and achieve provisioning use cases.
We leveraged Token-based Authentication
ConnectionJSON
----------------
{
"authentications":{
"netsuite":{
"properties":{
"SOAP_ENDPOINT":"https://baseurl/services/NetSuitePort_2020_1",
"ACCOUNT":"clientAccount",
"CONSUMER_KEY":"clientConsumerKey",
"CONSUMER_SECRET":"clientConsuemerSecret",
"TOKEN_ID":"clientsTokenID",
"TOKEN_SECRET":"clientsTokenSecret"
}
}
}
}
GrantAccess Json
-----------------
[{
"CONNECTION":"netsuite",
"RUNFOREACHENT": "TRUE",
"REQUESTXML":"${String timestamp=new Date().getTime().toLong().toString().substring(0, 10); String nonce=java.util.UUID.randomUUID().toString().replace('-', '').substring(0, 20); String signature=org.apache.commons.codec.digest.HmacUtils.hmacSha1( (CONSUMER_SECRET+'&'+TOKEN_SECRET).getBytes() , (ACCOUNT+'&'+CONSUMER_KEY+'&'+TOKEN_ID+'&'+nonce+'&'+timestamp).getBytes() ).encodeAsBase64(); return '<soapenv:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <soapenv:Header> <tokenPassport> <account>'+ACCOUNT+'</account> <consumerKey>'+CONSUMER_KEY+'</consumerKey> <token>'+TOKEN_ID+'</token> <nonce>'+nonce+'</nonce> <timestamp>'+timestamp+'</timestamp> <signature algorithm=\"HMAC-SHA1\">'+signature+'</signature> </tokenPassport> </soapenv:Header> <soapenv:Body>' + <platformMsg:update xmlns:platformMsg=\"urn:messages_2020_1.platform.webservices.netsuite.com\"> <platformMsg:record xsi:type=\"ns1:Employee\" externalId=\"'+account.accountId+'\" xmlns:ns1=\"urn:employees_2020_1.lists.webservices.netsuite.com\" xmlns:ns2=\"urn:core_2020_1.platform.webservices.netsuite.com\"> <ns1:entityId>'+account.name+'</ns1:entityId> <ns1:firstName>'+account.custompropertyA+'</ns1:firstName> <ns1:lastName>'+account.custompropertyB+'</ns1:lastName> <ns1:email>'+account.custompropertyC+'</ns1:email> <ns1:isInactive>0</ns1:isInactive> <ns1:department xsi:type=\"platformCore:RecordRef\" externalId=\"'+account.custompropertyD+'\"/> <ns1:class xsi:type=\"platformCore:RecordRef\" externalId=\"'+account.custompropertyE+'\"/> <ns1:subsidiary xsi:type=\"platformCore:RecordRef\" externalId=\"'+account.custompropertyF+'\"/> <ns1:comments>'+account.custompropertyG+'</ns1:comments> <ns1:supervisor xsi:type=\"platformCore:RecordRef\" internalId=\"'+account.custompropertyH+'\"/> <ns1:employeeType xsi:type=\"platformCore:RecordRef\" internalId=\"'+account.custompropertyI+'\"/> <ns1:giveAccess>1</ns1:giveAccess> <ns1:password>Test@12345</ns1:password> <ns1:password2>Test@12345</ns1:password2> <ns1:rolesList replaceAll=\"false\"> <ns1:roles> <ns1:selectedRole xsi:type=\"platformCore:RecordRef\" internalId=\"'+entitlement.entitlement_value+'\"/> </ns1:roles> </ns1:rolesList> </platformMsg:record> </platformMsg:update> + '</soapenv:Body> </soapenv:Envelope>';}",
"REQUESTPARAMS":{
"Content-Type":"text/xml",
"SOAPAction":"update"
},
"RESPONSEMAPPING":{
"AFTERSUBMITFAILED" : "Body.updateResponse.writeResponse.status.statusDetail.afterSubmitFailed",
"CODE" : "Body.updateResponse.writeResponse.status.statusDetail.code",
"MESSAGE" : "Body.updateResponse.writeResponse.status.statusDetail.message"
},
"SUCCESSCRITERIA": "AFTERSUBMITFAILED=false"
}]
AccountImport JSON
-------------------
{
"CONNECTION1":"netsuite",
"REQUESTXML1":"${String timestamp=new Date().getTime().toLong().toString().substring(0, 10); String nonce=java.util.UUID.randomUUID().toString().replace('-', '').substring(0, 20); String signature=org.apache.commons.codec.digest.HmacUtils.hmacSha1( (CONSUMER_SECRET+'&'+TOKEN_SECRET).getBytes() , (ACCOUNT+'&'+CONSUMER_KEY+'&'+TOKEN_ID+'&'+nonce+'&'+timestamp).getBytes() ).encodeAsBase64(); return '<soapenv:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <soapenv:Header> <tokenPassport> <account>'+ACCOUNT+'</account> <consumerKey>'+CONSUMER_KEY+'</consumerKey> <token>'+TOKEN_ID+'</token> <nonce>'+nonce+'</nonce> <timestamp>'+timestamp+'</timestamp> <signature algorithm=\"HMAC-SHA1\">'+signature+'</signature> </tokenPassport> </soapenv:Header> <soapenv:Body>' + (nsId != null && nsId != '' ? '<ns3:searchMoreWithId xmlns=\"urn:customization_2020_1.setup.webservices.netsuite.com\" xmlns:ns2=\"urn:core_2020_1.platform.webservices.netsuite.com\" xmlns:ns3=\"urn:messages_2020_1.platform.webservices.netsuite.com\"> <ns3:searchId>'+nsId+'</ns3:searchId> <ns3:pageIndex>'+PAGE_NUMBER+'</ns3:pageIndex> </ns3:searchMoreWithId>' : '<platformMsg:search xmlns:platformMsg=\"urn:messages_2020_1.platform.webservices.netsuite.com\"> <platformMsg:searchRecord xsi:type=\"ns2:EmployeeSearchAdvanced\" savedSearchId=\"18732\" xmlns:ns2=\"urn:employees_2020_1.lists.webservices.netsuite.com\"> </platformMsg:searchRecord> </platformMsg:search>' ) + '</soapenv:Body> </soapenv:Envelope>';}",
"REQUESTPARAMS1":{
"Content-Type":"text/xml",
"SOAPAction":"${nsId != null && nsId != '' ? 'searchMoreWithId' : 'search'}"
},
"RESPONSEDATAPATH1":"${nsId != null && nsId != '' ? 'Body.searchMoreWithIdResponse.searchResult.searchRowList.searchRow' : 'Body.searchResponse.searchResult.searchRowList.searchRow'}",
"RESPONSETOTALRESULTS1":"${nsId != null && nsId != '' ? 'Body.searchMoreWithIdResponse.searchResult.totalRecords' : 'Body.searchResponse.searchResult.totalRecords'}",
"RESPONSEPAGERESULTS1":"${nsId != null && nsId != '' ? 'Body.searchMoreWithIdResponse.searchResult.pageSize' : 'Body.searchResponse.searchResult.pageSize'}",
"ACCOUNTMAPPING1":"name:basic.entityId.searchValue,customproperty1:basic.email.searchValue,accountid:basic.externalId.searchValue.@externalId,customproperty2:basic.giveAccess.searchValue",
"ENTITLEMENTMAPPING1":{
"Role":"basic.role.searchValue.@internalId"
},
"RESPONSEMAPPING1":{
"nsId":"Body.searchResponse.searchResult.searchId"
}
}
Remove Access JSON
------------------
[{
"CONNECTION":"netsuite",
"RUNFOREACHENT": "TRUE",
"REQUESTXML":"${String timestamp=new Date().getTime().toLong().toString().substring(0, 10); String nonce=java.util.UUID.randomUUID().toString().replace('-', '').substring(0, 20); String signature=org.apache.commons.codec.digest.HmacUtils.hmacSha1( (CONSUMER_SECRET+'&'+TOKEN_SECRET).getBytes() , (ACCOUNT+'&'+CONSUMER_KEY+'&'+TOKEN_ID+'&'+nonce+'&'+timestamp).getBytes() ).encodeAsBase64(); return '<soapenv:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <soapenv:Header> <tokenPassport> <account>'+ACCOUNT+'</account> <consumerKey>'+CONSUMER_KEY+'</consumerKey> <token>'+TOKEN_ID+'</token> <nonce>'+nonce+'</nonce> <timestamp>'+timestamp+'</timestamp> <signature algorithm=\"HMAC-SHA1\">'+signature+'</signature> </tokenPassport> </soapenv:Header> <soapenv:Body>' + '<platformMsg:upsert xmlns:platformMsg=\"urn:messages_2020_1.platform.webservices.netsuite.com\"> <platformMsg:record xsi:type=\"ns1:CustomRecord\" externalId=\"'+account.accountId+'-'+entitlement.entitlement_value+'-'+new Date().format('yyyyMMddHHmmss')+'\" xmlns:ns1=\"urn:customization_2020_1.setup.webservices.netsuite.com\" xmlns:ns2=\"urn:core_2020_1.platform.webservices.netsuite.com\"> <customSetup:recType xsi:type=\"platformCore:RecordRef\" type=\"customRecord\" internalId=\"892\" xmlns:customSetup=\"urn:customization_2020_1.setup.webservices.netsuite.com\"/> <ns1:customFieldList> <ns2:customField xsi:type=\"ns2:SelectCustomFieldRef\" scriptId=\"custrecord_emp_date\"> <ns2:value typeId=\"-4\" internalId=\"'+account.accountId+'\"/> </ns2:customField> <ns2:customField xsi:type=\"ns2:SelectCustomFieldRef\" scriptId=\"custrecord_role\"> <ns2:value typeId=\"-118\" internalId=\"'+entitlement.entitlement_value+'\"/> </ns2:customField> <ns2:customField xsi:type=\"ns2:DateCustomFieldRef\" scriptId=\"custrecord_exp_date\"> <ns2:value>new Date().format('yyyy-MM-dd')+'T11:20:00.000-07:00'</ns2:value> </ns2:customField> <ns2:customField xsi:type=\"ns2:BooleanCustomFieldRef\" scriptId=\"custrecord_expiry_notification_req\"> <ns2:value>1</ns2:value> </ns2:customField> </ns1:customFieldList> </platformMsg:record> </platformMsg:upsert>' + '</soapenv:Body> </soapenv:Envelope>';}",
"REQUESTPARAMS":{
"Content-Type":"text/xml",
"SOAPAction":"upsert"
},
"RESPONSEMAPPING":{
"AFTERSUBMITFAILED" : "Body.updateResponse.writeResponse.status.@isSuccess",
"CODE" : "Body.updateResponse.writeResponse.status.statusDetail.code",
"MESSAGE" : "Body.updateResponse.writeResponse.status.statusDetail.message"
},
"SUCCESSCRITERIA": "AFTERSUBMITFAILED=true"
}]
UpdateAccount JSON
------------------
[{
"CONNECTION":"netsuite",
"RUNFOREACHENT": "TRUE",
"REQUESTXML":"${String timestamp=new Date().getTime().toLong().toString().substring(0, 10); String nonce=java.util.UUID.randomUUID().toString().replace('-', '').substring(0, 20); String signature=org.apache.commons.codec.digest.HmacUtils.hmacSha1( (CONSUMER_SECRET+'&'+TOKEN_SECRET).getBytes() , (ACCOUNT+'&'+CONSUMER_KEY+'&'+TOKEN_ID+'&'+nonce+'&'+timestamp).getBytes() ).encodeAsBase64(); return '<soapenv:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> <soapenv:Header> <tokenPassport> <account>'+ACCOUNT+'</account> <consumerKey>'+CONSUMER_KEY+'</consumerKey> <token>'+TOKEN_ID+'</token> <nonce>'+nonce+'</nonce> <timestamp>'+timestamp+'</timestamp> <signature algorithm=\"HMAC-SHA1\">'+signature+'</signature> </tokenPassport> </soapenv:Header> <soapenv:Body>' + <platformMsg:update xmlns:platformMsg=\"urn:messages_2020_1.platform.webservices.netsuite.com\"> <platformMsg:record xsi:type=\"ns1:Employee\" externalId=\"'+account.accountId+'\" xmlns:ns1=\"urn:employees_2020_1.lists.webservices.netsuite.com\" xmlns:ns2=\"urn:core_2020_1.platform.webservices.netsuite.com\"> <ns1:entityId>'+account.name+'</ns1:entityId> <ns1:firstName>'+account.custompropertyA+'</ns1:firstName> <ns1:lastName>'+account.custompropertyB+'</ns1:lastName> <ns1:email>'+account.custompropertyC+'</ns1:email> <ns1:isInactive>0</ns1:isInactive> <ns1:department xsi:type=\"platformCore:RecordRef\" externalId=\"'+account.custompropertyD+'\"/> <ns1:class xsi:type=\"platformCore:RecordRef\" externalId=\"'+account.custompropertyE+'\"/> <ns1:subsidiary xsi:type=\"platformCore:RecordRef\" externalId=\"'+account.custompropertyF+'\"/> <ns1:comments>'+account.custompropertyG+'</ns1:comments> <ns1:supervisor xsi:type=\"platformCore:RecordRef\" internalId=\"'+account.custompropertyH+'\"/> <ns1:employeeType xsi:type=\"platformCore:RecordRef\" internalId=\"'+account.custompropertyI+'\"/> <ns1:customFieldList> <ns2:customField xsi:type=\"ns2:StringCustomFieldRef\" scriptId=\"custentity1\"> <ns2:value>8028305</ns2:value> </ns2:customField> <ns2:customField xsi:type=\"ns2:StringCustomFieldRef\" scriptId=\"custentity_gbt_supplier\"> <ns2:value/> </ns2:customField> <ns2:customField xsi:type=\"ns2:StringCustomFieldRef\" scriptId=\"custentity_managementlevel\"> <ns2:value>40</ns2:value> </ns2:customField> <ns2:customField xsi:type=\"ns2:SelectCustomFieldRef\" scriptId=\"custentity_workday_status\"> <ns2:value typeId=\"1084\" internalId=\"1\"/> </ns2:customField> <ns2:customField xsi:type=\"ns2:StringCustomFieldRef\" scriptId=\"custentity_gbt_id\"> <ns2:value>8028305</ns2:value> </ns2:customField> <ns2:customField xsi:type=\"ns2:StringCustomFieldRef\" scriptId=\"custentity_wd_gbt_id\"> <ns2:value>8028305</ns2:value> </ns2:customField> </ns1:customFieldList> </platformMsg:record> </platformMsg:update> + '</soapenv:Body> </soapenv:Envelope>';}",
"REQUESTPARAMS":{
"Content-Type":"text/xml",
"SOAPAction":"update"
},
"RESPONSEMAPPING":{
"AFTERSUBMITFAILED" : "Body.updateResponse.writeResponse.status.statusDetail.afterSubmitFailed",
"CODE" : "Body.updateResponse.writeResponse.status.statusDetail.code",
"MESSAGE" : "Body.updateResponse.writeResponse.status.statusDetail.message"
},
"SUCCESSCRITERIA": "AFTERSUBMITFAILED=false"
}]
Hello @sai_sp ,
I used the above details to initiate the connection between Netsuite instance & Saviynt, and the connection was successful. however the jobs to import accounts is failing. below is the log.
I have updated the JSON's mentioned above in the connection.
kindly help with the same.
Regards,
Vidhi.
@Vidhimehta - Did you find the issue with the json's?
CC: @sai_sp
Hello Everyone,
I tried SOAP and spent one month, but I had no luck. I am saying that Saviynt does not support the SOAP API for NetSuite. Nothing makes sense to referring this article for NetSuite integration